Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update #21

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified bin/console
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion exe/metadata
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ else
end

metadata = client.get_metadata(block_hash)
puts JSON.pretty_generate(metadata)
puts metadata.to_json
end
2 changes: 2 additions & 0 deletions lib/scale_rb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ def debug(key, value)

require 'scale_rb/types'
require 'scale_rb/portable_registry'
require 'scale_rb/old_registry'
require 'scale_rb/codec'

require 'scale_rb/metadata/metadata'
require 'scale_rb/runtime_types'

require 'scale_rb/hasher'
require 'scale_rb/storage_helper'
Expand Down
10 changes: 5 additions & 5 deletions lib/scale_rb/call_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module CallHelper
# "0x05000a1287977578f888bdc1c7627781af1cc000e6ab1300004c31b8d9a798"._to_bytes
def self.decode_call(callbytes, metadata)
pallet_index = callbytes[0]
pallet = Metadata.get_module_by_index(pallet_index, metadata)
pallet = metadata.pallet_by_index(pallet_index)

# Remove the pallet_index
# The callbytes we used below should not contain the pallet index.
Expand All @@ -20,7 +20,7 @@ def self.decode_call(callbytes, metadata)
decoded = Codec.decode(
calls_type_id,
callbytes_without_pallet_index,
Metadata.build_registry(metadata)
metadata.build_registry
)&.first

{
Expand All @@ -34,9 +34,9 @@ def self.decode_call(callbytes, metadata)
# {:pallet_name=>"Deposit", :call_name=>"claim", :call=>:claim]}
# {:pallet_name=>"Balances", :call_name=>"transfer", :call=>{:transfer=>{:dest=>[10, 18, 135, 151, 117, 120, 248, 136, 189, 193, 199, 98, 119, 129, 175, 28, 192, 0, 230, 171], :value=>11000000000000000000}}]}
def self.encode_call(call, metadata)
calls_type_id = Metadata.get_calls_type_id(call[:pallet_name], metadata)
pallet_index = Metadata.get_module(call[:pallet_name], metadata)._get(:index)
[pallet_index] + Codec.encode(calls_type_id, call[:call], Metadata.build_registry(metadata))
calls_type_id = metadata.calls_type_id(call[:pallet_name])
pallet_index = metadata.pallet(call[:pallet_name])[:index]
[pallet_index] + Codec.encode(calls_type_id, call[:call], metadata.build_registry)
end
end
end
8 changes: 3 additions & 5 deletions lib/scale_rb/client/client_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module ClientExt
def get_metadata(block_hash = nil)
block_hash ||= chain_getHead
metadata_hex = state_getMetadata(block_hash)
Metadata.decode_metadata(metadata_hex)
Metadata::Metadata.from_hex(metadata_hex)
end

# Get decoded storage at block_hash
Expand Down Expand Up @@ -134,10 +134,8 @@ def get_storage1(block_hash, pallet_name, item_name, key, value, registry)
def get_storage2(block_hash, pallet_name, item_name, params, metadata)
raise 'Metadata should not be nil' if metadata.nil?

registry = Metadata.build_registry(metadata)
item = Metadata.get_storage_item(
pallet_name, item_name, metadata
)
registry = metadata.build_registry
item = metadata.storage(pallet_name, item_name)
raise "No such storage item: `#{pallet_name}`.`#{item_name}`" if item.nil?

modifier = item._get(:modifier) # Default | Optional
Expand Down
34 changes: 34 additions & 0 deletions lib/scale_rb/extrinsic_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

module ScaleRb
module ExtrinsicHelper
def decode_extrinsic(bytes, metadata_prefixed)
meta = bytes[0]
signed = (meta & 0x80) == 0x80
version = (meta & 0x7f)

raise "Unsupported version: #{version}" unless version == 4

nil unless signed
end

def patch_types(registry, metadata_prefixed)
add_signed_extensions_type(metadata_prefixed.signed_extensions, registry)
end

private

def add_signed_extensions_type(signed_extensions, registry)
type = Types::StructType.new(
fields: signed_extensions.map do |signed_extension|
Types::Field.new(
name: Utils.camelize(signed_extension._get(:identifier)),
type: signed_extension._get(:type)
)
end,
registry:
)
registry.add_type(type)
end
end
end
92 changes: 49 additions & 43 deletions lib/scale_rb/metadata/metadata.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require_relative './registry'

require_relative './metadata_v9'
require_relative './metadata_v10'
require_relative './metadata_v11'
Expand All @@ -13,66 +11,74 @@
# https://github.com/paritytech/frame-metadata/blob/main/frame-metadata/src/lib.rs#L85
module ScaleRb
module Metadata
class << self
def decode_metadata(hex)
bytes = ScaleRb::Utils.hex_to_u8a(hex)

registry = ScaleRb::Metadata::Registry.new TYPES
metadata, = ScaleRb::Codec.decode('MetadataPrefixed', bytes, registry)
metadata
class Metadata
attr_reader :magic_number, :version, :metadata, :types

def initialize(metadata_prefixed)
@metadata_prefixed = metadata_prefixed
@magic_number = @metadata_prefixed[:magicNumber]
metadata = @metadata_prefixed[:metadata]
@version = metadata.keys.first
raise "Unsupported metadata version: #{@version}" unless @version == :V14

@metadata = metadata[@version]
@types = @metadata.dig(:lookup, :types)
end

def build_registry(metadata_prefixed)
types = ScaleRb::Utils.get(metadata_prefixed, :metadata, :V14, :lookup, :types)
ScaleRb::PortableRegistry.new(types)
def self.from_hex(hex)
metadata_prefixed, = ScaleRb::Codec.decode('MetadataPrefixed', Utils.hex_to_u8a(hex), OldRegistry.new(TYPES))
Metadata.new(metadata_prefixed)
end

def get_module(pallet_name, metadata_prefixed)
metadata = Utils.get(metadata_prefixed, :metadata)
version = metadata.keys.first
raise NotImplementedError, version unless %i[V14].include?(version)

Metadata.const_get("Metadata#{version.upcase}").get_module(pallet_name, metadata_prefixed)
def self.from_json(str)
metadata_prefixed = JSON.parse(str, symbolize_names: true)
Metadata.new(metadata_prefixed)
end

def get_module_by_index(pallet_index, metadata_prefixed)
metadata = Utils.get(metadata_prefixed, :metadata)
version = metadata.keys.first.to_sym
raise NotImplementedError, version unless %i[V14].include?(version)
def to_json(*_args)
JSON.pretty_generate(@metadata_prefixed)
end

Metadata.const_get("Metadata#{version.upcase}").get_module_by_index(pallet_index, metadata_prefixed)
def build_registry
ScaleRb::PortableRegistry.new(@metadata.dig(:lookup, :types))
end

def get_storage_item(pallet_name, item_name, metadata_prefixed)
metadata = Utils.get(metadata_prefixed, :metadata)
version = metadata.keys.first.to_sym
raise NotImplementedError, version unless %i[V14].include?(version)
def pallet(pallet_name)
@metadata[:pallets].find do |pallet|
pallet[:name] == pallet_name
end
end

Metadata.const_get("Metadata#{version.upcase}").get_storage_item(pallet_name, item_name, metadata_prefixed)
def pallet_by_index(pallet_index)
@metadata[:pallets].find do |pallet|
pallet[:index] == pallet_index
end
end

def get_calls_type(pallet_name, metadata_prefixed)
metadata = Utils.get(metadata_prefixed, :metadata)
version = metadata.keys.first.to_sym
raise NotImplementedError, version unless %i[V14].include?(version)
def storage(pallet_name, item_name)
pallet = pallet(pallet_name)
raise "Pallet `#{pallet_name}` not found" if pallet.nil?

Metadata.const_get("Metadata#{version.upcase}").get_calls_type(pallet_name, metadata_prefixed)
pallet.dig(:storage, :items).find do |item|
item[:name] == item_name
end
end

def get_calls_type_id(pallet_name, metadata_prefixed)
metadata = Utils.get(metadata_prefixed, :metadata)
version = metadata.keys.first.to_sym
raise NotImplementedError, version unless %i[V14].include?(version)
def calls_type_id(pallet_name)
pallet = pallet(pallet_name)
raise "Pallet `#{pallet_name}` not found" if pallet.nil?

Metadata.const_get("Metadata#{version.upcase}").get_calls_type_id(pallet_name, metadata_prefixed)
pallet.dig(:calls, :type)
end

def get_call_type(pallet_name, call_name, metadata_prefixed)
metadata = Utils.get(metadata_prefixed, :metadata)
version = metadata.keys.first.to_sym
raise NotImplementedError, version unless %i[V14].include?(version)
def call(pallet_name, call_name)
calls_type_id = calls_type_id(pallet_name)
calls_type = @types[calls_type_id]
raise 'Calls type is not correct' if calls_type.nil?

Metadata.const_get("Metadata#{version.upcase}").get_call_type(pallet_name, call_name, metadata_prefixed)
calls_type.dig(:type, :def, :variant, :variants).find do |variant|
variant[:name].downcase == call_name.downcase
end
end
end

Expand Down
12 changes: 9 additions & 3 deletions lib/scale_rb/metadata/metadata_v14.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ module ScaleRb
module Metadata
module MetadataV14
class << self
def build_registry(metadata)
types = metadata._get(:lookup, :types)
ScaleRb.build_types(types)
def build_registry(metadata_prefixed)
types = ScaleRb::Utils.get(metadata_prefixed, :metadata, :V14, :lookup, :types)
ScaleRb::PortableRegistry.new(types)
end

def get_module(pallet_name, metadata_prefixed)
Expand Down Expand Up @@ -50,6 +50,12 @@ def get_call_type(pallet_name, call_name, metadata_prefixed)
variant._get(:name).downcase == call_name.downcase
end
end

def signature_type(metadata_prefixed); end

def signed_extensions(metadata_prefixed)
ScaleRb::Utils.get(metadata_prefixed, :metadata, :V14, :extrinsic, :signedExtensions)
end
end

TYPES = {
Expand Down
Loading