scale_rb 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/lib/address.rb +43 -35
- data/lib/client/http_client.rb +2 -157
- data/lib/client/http_client_metadata.rb +78 -0
- data/lib/client/http_client_storage.rb +180 -0
- data/lib/codec.rb +17 -18
- data/lib/scale_rb/version.rb +1 -1
- data/lib/storage_helper.rb +11 -11
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d49c850c60bd8f6807d0c04995d3b8a5262f63dc627b585e683d774e91ed96ab
|
4
|
+
data.tar.gz: adbba1bbba8cf9bbf3f559893a2b69f90d94a41a259db713f1a7db6dcb83b29f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0b06fa722621edab033346e30d78ea8096d98fe032f285845f2685593b6cce266aaa18cd8126cdf1632b1e85f6bcdeea6e6858c12534608ab7fb98a27dbd777
|
7
|
+
data.tar.gz: e57dc6323f7bd0024041ce0ed46bcc006f588e770f895d530d836755981248e1d37abf4d33c529da0e5db57dac231a941bcd506a8822170b8f074b72ba4877cc
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scale_rb (0.1.
|
4
|
+
scale_rb (0.1.15)
|
5
5
|
base58
|
6
6
|
blake2b_rs (~> 0.1.4)
|
7
7
|
xxhash
|
@@ -14,7 +14,7 @@ GEM
|
|
14
14
|
ffi (~> 1.0)
|
15
15
|
thermite (~> 0)
|
16
16
|
diff-lcs (1.5.0)
|
17
|
-
ffi (1.
|
17
|
+
ffi (1.16.3)
|
18
18
|
minitar (0.9)
|
19
19
|
rake (12.3.3)
|
20
20
|
rspec (3.11.0)
|
data/lib/address.rb
CHANGED
@@ -14,7 +14,7 @@ class Address
|
|
14
14
|
# Darwinia Live
|
15
15
|
18,
|
16
16
|
# Dothereum (SS58, AccountId)
|
17
|
-
20, 21,
|
17
|
+
20, 21,
|
18
18
|
# Generic Substrate wildcard (SS58, AccountId)
|
19
19
|
42, 43,
|
20
20
|
|
@@ -30,54 +30,62 @@ class Address
|
|
30
30
|
]
|
31
31
|
|
32
32
|
class << self
|
33
|
-
|
34
33
|
def array_to_hex_string(arr)
|
35
34
|
body = arr.map { |i| i.to_s(16).rjust(2, '0') }.join
|
36
35
|
"0x#{body}"
|
37
36
|
end
|
38
37
|
|
39
|
-
def decode(address, addr_type = 42,
|
38
|
+
def decode(address, addr_type = 42, _ignore_checksum = true)
|
40
39
|
decoded = Base58.base58_to_binary(address, :bitcoin)
|
41
40
|
is_pubkey = decoded.size == 35
|
42
41
|
|
43
|
-
size = decoded.size - (
|
42
|
+
size = decoded.size - (is_pubkey ? 2 : 1)
|
43
|
+
|
44
|
+
prefix = decoded[0, 1].unpack1('C*')
|
44
45
|
|
45
|
-
|
46
|
+
raise 'Invalid address type' unless TYPES.include?(addr_type)
|
46
47
|
|
47
|
-
raise "Invalid address type" unless TYPES.include?(addr_type)
|
48
|
-
|
49
48
|
hash_bytes = make_hash(decoded[0, size])
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
is_valid_checksum =
|
50
|
+
if is_pubkey
|
51
|
+
decoded[-2].unpack1('C*') == hash_bytes[0] && decoded[-1].unpack1('C*') == hash_bytes[1]
|
52
|
+
else
|
53
|
+
decoded[-1].unpack1('C*') == hash_bytes[0]
|
54
|
+
end
|
55
55
|
|
56
56
|
# raise "Invalid decoded address checksum" unless is_valid_checksum && ignore_checksum
|
57
57
|
|
58
|
-
decoded[1...size].
|
58
|
+
decoded[1...size].unpack1('H*')
|
59
59
|
end
|
60
60
|
|
61
|
-
|
62
61
|
def encode(pubkey, addr_type = 42)
|
63
62
|
pubkey = pubkey[2..-1] if pubkey =~ /^0x/i
|
64
|
-
key = [pubkey].pack(
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
63
|
+
key = [pubkey].pack('H*')
|
64
|
+
|
65
|
+
pubkey_bytes = key.bytes
|
66
|
+
|
67
|
+
checksum_length = case pubkey_bytes.length
|
68
|
+
when 32, 33
|
69
|
+
2
|
70
|
+
when 1, 2, 4, 8
|
71
|
+
1
|
72
|
+
else
|
73
|
+
raise 'Invalid pubkey length'
|
74
|
+
end
|
75
|
+
|
76
|
+
ss58_format_bytes = if addr_type < 64
|
77
|
+
[addr_type].pack('C*')
|
78
|
+
else
|
79
|
+
[
|
80
|
+
((ss58_format & 0b0000_0000_1111_1100) >> 2) | 0b0100_0000,
|
81
|
+
(ss58_format >> 8) | ((ss58_format & 0b0000_0000_0000_0011) << 6)
|
82
|
+
].pack('C*')
|
83
|
+
end
|
84
|
+
|
85
|
+
input_bytes = ss58_format_bytes.bytes + pubkey_bytes
|
86
|
+
checksum = Blake2b.hex(SS58_PREFIX.bytes + input_bytes, 64).to_bytes
|
87
|
+
|
88
|
+
Base58.binary_to_base58((input_bytes + checksum[0...checksum_length]).pack('C*'), :bitcoin)
|
81
89
|
end
|
82
90
|
|
83
91
|
def make_hash(body)
|
@@ -87,11 +95,11 @@ class Address
|
|
87
95
|
def is_ss58_address?(address)
|
88
96
|
begin
|
89
97
|
decode(address)
|
90
|
-
rescue
|
98
|
+
rescue StandardError
|
91
99
|
return false
|
92
100
|
end
|
93
|
-
|
101
|
+
true
|
94
102
|
end
|
95
|
-
|
96
103
|
end
|
97
|
-
end
|
104
|
+
end
|
105
|
+
|
data/lib/client/http_client.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'uri'
|
4
4
|
require 'net/http'
|
5
5
|
require 'json'
|
6
|
+
require_relative './http_client_metadata'
|
7
|
+
require_relative './http_client_storage'
|
6
8
|
|
7
9
|
# TODO: method_name = cmd.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
|
8
10
|
module ScaleRb
|
@@ -59,163 +61,6 @@ module ScaleRb
|
|
59
61
|
result = json_rpc_call(url, 'rpc_methods', [])
|
60
62
|
result['methods']
|
61
63
|
end
|
62
|
-
|
63
|
-
def get_metadata(url, at = nil)
|
64
|
-
hex = state_getMetadata(url, at)
|
65
|
-
Metadata.decode_metadata(hex.strip.to_bytes)
|
66
|
-
end
|
67
|
-
|
68
|
-
def query_storage_at(url, storage_keys, type_id, default, registry, at = nil)
|
69
|
-
result = state_queryStorageAt(url, storage_keys, at)
|
70
|
-
result.map do |item|
|
71
|
-
item['changes'].map do |change|
|
72
|
-
storage_key = change[0]
|
73
|
-
data = change[1] || default
|
74
|
-
storage = data.nil? ? nil : PortableCodec.decode(type_id, data.to_bytes, registry)[0]
|
75
|
-
{ storage_key: storage_key, storage: storage }
|
76
|
-
end
|
77
|
-
end.flatten
|
78
|
-
end
|
79
|
-
|
80
|
-
def get_storage_keys_by_partial_key(url, partial_storage_key, start_key = nil, at = nil)
|
81
|
-
storage_keys = state_getKeysPaged(url, partial_storage_key, 1000, start_key, at)
|
82
|
-
if storage_keys.length == 1000
|
83
|
-
storage_keys + get_storage_keys_by_partial_key(url, partial_storage_key, storage_keys.last, at)
|
84
|
-
else
|
85
|
-
storage_keys
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def get_storages_by_partial_key(url, partial_storage_key, type_id_of_value, default, registry, at = nil)
|
90
|
-
storage_keys = get_storage_keys_by_partial_key(url, partial_storage_key, partial_storage_key, at)
|
91
|
-
storage_keys.each_slice(250).map do |slice|
|
92
|
-
query_storage_at(
|
93
|
-
url,
|
94
|
-
slice,
|
95
|
-
type_id_of_value,
|
96
|
-
default,
|
97
|
-
registry,
|
98
|
-
at
|
99
|
-
)
|
100
|
-
end.flatten
|
101
|
-
end
|
102
|
-
|
103
|
-
# 1. Plain
|
104
|
-
# key: nil
|
105
|
-
# value: { type: 3, modifier: 'Default', callback: '' }
|
106
|
-
#
|
107
|
-
# 2. Map
|
108
|
-
# key: { value: value, type: 0, hashers: ['Blake2128Concat'] }
|
109
|
-
# value: { type: 3, modifier: 'Default', callback: '' }
|
110
|
-
#
|
111
|
-
# 3. Map, but key.value is nil
|
112
|
-
# key: { value: nil, type: 0, hashers: ['Blake2128Concat'] }
|
113
|
-
# value: { type: 3, modifier: 'Default', callback: '' }
|
114
|
-
#
|
115
|
-
# example:
|
116
|
-
# 'System',
|
117
|
-
# 'Account',
|
118
|
-
# key = {
|
119
|
-
# value: [['0x724d50824542b56f422588421643c4a162b90b5416ef063f2266a1eae6651641'.to_bytes]], # [AccountId]
|
120
|
-
# type: 0,
|
121
|
-
# hashers: ['Blake2128Concat']
|
122
|
-
# },
|
123
|
-
# value = {
|
124
|
-
# type: 3,
|
125
|
-
# modifier: 'Default',
|
126
|
-
# callback: '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
127
|
-
# },
|
128
|
-
# ..
|
129
|
-
#
|
130
|
-
# TODO: part of the key is provided, but not all
|
131
|
-
def get_storage(url, pallet_name, item_name, key, value, registry, at = nil)
|
132
|
-
# map, but no key's value provided. get all storages under the partial storage key
|
133
|
-
if key && (key[:value].nil? || key[:value].empty?)
|
134
|
-
partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name).to_hex
|
135
|
-
get_storages_by_partial_key(
|
136
|
-
url,
|
137
|
-
partial_storage_key,
|
138
|
-
value[:type],
|
139
|
-
value[:modifier] == 'Default' ? value[:fallback] : nil,
|
140
|
-
registry,
|
141
|
-
at
|
142
|
-
)
|
143
|
-
else
|
144
|
-
storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
|
145
|
-
data = state_getStorage(url, storage_key, at)
|
146
|
-
StorageHelper.decode_storage(data, value[:type], value[:modifier] == 'Optional', value[:fallback], registry)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def get_storage2(url, pallet_name, item_name, value_of_key, metadata, at = nil)
|
151
|
-
raise 'Metadata should not be nil' if metadata.nil?
|
152
|
-
|
153
|
-
registry = Metadata.build_registry(metadata)
|
154
|
-
item = Metadata.get_storage_item(pallet_name, item_name, metadata)
|
155
|
-
raise "No such storage item: `#{pallet_name}`.`#{item_name}`" if item.nil?
|
156
|
-
|
157
|
-
modifier = item._get(:modifier) # Default | Optional
|
158
|
-
fallback = item._get(:fallback)
|
159
|
-
type = item._get(:type)
|
160
|
-
|
161
|
-
plain = type._get(:plain)
|
162
|
-
map = type._get(:map)
|
163
|
-
# debug
|
164
|
-
|
165
|
-
key, value =
|
166
|
-
if plain
|
167
|
-
[
|
168
|
-
nil,
|
169
|
-
{ type: plain, modifier: modifier, fallback: fallback }
|
170
|
-
]
|
171
|
-
elsif map
|
172
|
-
[
|
173
|
-
{ value: value_of_key, type: map._get(:key), hashers: map._get(:hashers) },
|
174
|
-
{ type: map._get(:value), modifier: modifier, fallback: fallback }
|
175
|
-
]
|
176
|
-
else
|
177
|
-
raise 'NoSuchStorageType'
|
178
|
-
end
|
179
|
-
get_storage(url, pallet_name, item_name, key, value, registry, at)
|
180
|
-
end
|
181
|
-
|
182
|
-
# get_storage3 is a more ruby style function
|
183
|
-
#
|
184
|
-
# pallet_name and storage_name is pascal style like 'darwinia_staking'
|
185
|
-
def get_storage3(url, metadata, pallet_name, storage_name, key_part1: nil, key_part2: nil, at: nil)
|
186
|
-
pallet_name = to_pascal pallet_name
|
187
|
-
storage_name = to_pascal storage_name
|
188
|
-
ScaleRb.logger.debug "#{pallet_name}.#{storage_name}(#{[key_part1, key_part2].compact.join(', ')})"
|
189
|
-
|
190
|
-
key = [key_part1, key_part2].compact.map { |part_of_key| c(part_of_key) }
|
191
|
-
ScaleRb.logger.debug "converted key: #{key}"
|
192
|
-
|
193
|
-
get_storage2(
|
194
|
-
url,
|
195
|
-
pallet_name,
|
196
|
-
storage_name,
|
197
|
-
key,
|
198
|
-
metadata,
|
199
|
-
at
|
200
|
-
)
|
201
|
-
end
|
202
|
-
|
203
|
-
private
|
204
|
-
|
205
|
-
def to_pascal(str)
|
206
|
-
str.split('_').collect(&:capitalize).join
|
207
|
-
end
|
208
|
-
|
209
|
-
# convert key to byte array
|
210
|
-
def c(key)
|
211
|
-
if key.start_with?('0x')
|
212
|
-
key.to_bytes
|
213
|
-
elsif key.to_i.to_s == key # check if key is a number
|
214
|
-
key.to_i
|
215
|
-
else
|
216
|
-
key
|
217
|
-
end
|
218
|
-
end
|
219
64
|
end
|
220
65
|
end
|
221
66
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module ScaleRb
|
5
|
+
module HttpClient
|
6
|
+
class << self
|
7
|
+
def get_metadata(url, at = nil)
|
8
|
+
hex = state_getMetadata(url, at)
|
9
|
+
Metadata.decode_metadata(hex.strip.to_bytes)
|
10
|
+
end
|
11
|
+
|
12
|
+
# cached version of get_metadata
|
13
|
+
# get metadata from cache first
|
14
|
+
def get_metadata_cached(url, at: nil, dir: nil)
|
15
|
+
dir = ENV['SCALE_RB_METADATA_DIR'] || File.join(Dir.pwd, 'metadata') if dir.nil?
|
16
|
+
|
17
|
+
at = ScaleRb::HttpClient.chain_getFinalizedHead(url) if at.nil?
|
18
|
+
spec_name, spec_version = get_spec(url, at)
|
19
|
+
|
20
|
+
# get metadata from cache first
|
21
|
+
metadata = metadata_cached(
|
22
|
+
spec_name: spec_name,
|
23
|
+
spec_version: spec_version,
|
24
|
+
dir: dir
|
25
|
+
)
|
26
|
+
return metadata if metadata
|
27
|
+
|
28
|
+
# get metadata from rpc
|
29
|
+
metadata = ScaleRb::HttpClient.get_metadata(url, at)
|
30
|
+
|
31
|
+
# cache it
|
32
|
+
ScaleRb.logger.debug "caching metadata `#{spec_name}_#{spec_version}.json`"
|
33
|
+
save_metadata_to_file(
|
34
|
+
spec_name: spec_name,
|
35
|
+
spec_version: spec_version,
|
36
|
+
metadata: metadata,
|
37
|
+
dir: dir
|
38
|
+
)
|
39
|
+
|
40
|
+
metadata
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def get_spec(url, at)
|
46
|
+
runtime_version = ScaleRb::HttpClient.state_getRuntimeVersion(url, at)
|
47
|
+
spec_name = runtime_version['specName']
|
48
|
+
spec_version = runtime_version['specVersion']
|
49
|
+
[spec_name, spec_version]
|
50
|
+
end
|
51
|
+
|
52
|
+
def metadata_cached(spec_name:, spec_version:, dir:)
|
53
|
+
raise 'spec_version is required' unless spec_version
|
54
|
+
raise 'spec_name is required' unless spec_name
|
55
|
+
|
56
|
+
file_path = File.join(dir, "#{spec_name}_#{spec_version}.json")
|
57
|
+
return unless File.exist?(file_path)
|
58
|
+
|
59
|
+
ScaleRb.logger.debug "found metadata `#{spec_name}_#{spec_version}.json` in cache"
|
60
|
+
JSON.parse(File.read(file_path))
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_metadata_to_file(spec_name:, spec_version:, metadata:, dir:)
|
64
|
+
FileUtils.mkdir_p(dir)
|
65
|
+
|
66
|
+
File.open(File.join(dir, "#{spec_name}_#{spec_version}.json"), 'w') do |f|
|
67
|
+
f.write(JSON.pretty_generate(metadata))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def require_block_hash_correct(url, block_hash)
|
72
|
+
return unless ScaleRb::HttpClient.chain_getHeader(url, block_hash).nil?
|
73
|
+
|
74
|
+
raise 'Unable to retrieve header and parent from supplied hash'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module ScaleRb
|
2
|
+
module HttpClient
|
3
|
+
class << self
|
4
|
+
# get_storage3 is a more ruby style function
|
5
|
+
#
|
6
|
+
# pallet_name and storage_name is pascal style like 'darwinia_staking'
|
7
|
+
def get_storage3(url, pallet_name, storage_name, key_part1: nil, key_part2: nil, metadata: nil, at: nil)
|
8
|
+
# Get metadata if not provided, and cache it.
|
9
|
+
# The default dir is `metadata` dir under the caller's dir.
|
10
|
+
# You can change it by setting `SCALE_RB_METADATA_DIR` env variable
|
11
|
+
metadata = get_metadata_cached(url, at: at) if metadata.nil?
|
12
|
+
|
13
|
+
pallet_name = to_pascal pallet_name
|
14
|
+
storage_name = to_pascal storage_name
|
15
|
+
ScaleRb.logger.debug "#{pallet_name}.#{storage_name}(#{[key_part1, key_part2].compact.join(', ')})"
|
16
|
+
|
17
|
+
key = [key_part1, key_part2].compact.map { |part_of_key| c(part_of_key) }
|
18
|
+
ScaleRb.logger.debug "converted key: #{key}"
|
19
|
+
|
20
|
+
get_storage2(
|
21
|
+
url,
|
22
|
+
pallet_name,
|
23
|
+
storage_name,
|
24
|
+
key,
|
25
|
+
metadata,
|
26
|
+
at
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def query_storage_at(url, storage_keys, type_id, default, registry, at = nil)
|
33
|
+
result = state_queryStorageAt(url, storage_keys, at)
|
34
|
+
result.map do |item|
|
35
|
+
item['changes'].map do |change|
|
36
|
+
storage_key = change[0]
|
37
|
+
data = change[1] || default
|
38
|
+
storage = data.nil? ? nil : PortableCodec.decode(type_id, data.to_bytes, registry)[0]
|
39
|
+
{ storage_key: storage_key, storage: storage }
|
40
|
+
end
|
41
|
+
end.flatten
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_storage_keys_by_partial_key(url, partial_storage_key, start_key = nil, at = nil)
|
45
|
+
storage_keys = state_getKeysPaged(url, partial_storage_key, 1000, start_key, at)
|
46
|
+
if storage_keys.length == 1000
|
47
|
+
storage_keys + get_storage_keys_by_partial_key(url, partial_storage_key, storage_keys.last, at)
|
48
|
+
else
|
49
|
+
storage_keys
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_storages_by_partial_key(url, partial_storage_key, type_id_of_value, default, registry, at = nil)
|
54
|
+
storage_keys = get_storage_keys_by_partial_key(url, partial_storage_key, partial_storage_key, at)
|
55
|
+
storage_keys.each_slice(250).map do |slice|
|
56
|
+
query_storage_at(
|
57
|
+
url,
|
58
|
+
slice,
|
59
|
+
type_id_of_value,
|
60
|
+
default,
|
61
|
+
registry,
|
62
|
+
at
|
63
|
+
)
|
64
|
+
end.flatten
|
65
|
+
end
|
66
|
+
|
67
|
+
# 1. Plain
|
68
|
+
# key: nil
|
69
|
+
# value: { type: 3, modifier: 'Default', callback: '' }
|
70
|
+
#
|
71
|
+
# 2. Map
|
72
|
+
# key: { value: value, type: 0, hashers: ['Blake2128Concat'] }
|
73
|
+
# value: { type: 3, modifier: 'Default', callback: '' }
|
74
|
+
#
|
75
|
+
# 3. Map, but key.value is nil
|
76
|
+
# key: { value: nil, type: 0, hashers: ['Blake2128Concat'] }
|
77
|
+
# value: { type: 3, modifier: 'Default', callback: '' }
|
78
|
+
#
|
79
|
+
# example:
|
80
|
+
# 'System',
|
81
|
+
# 'Account',
|
82
|
+
# key = {
|
83
|
+
# value: [['0x724d50824542b56f422588421643c4a162b90b5416ef063f2266a1eae6651641'.to_bytes]], # [AccountId]
|
84
|
+
# type: 0,
|
85
|
+
# hashers: ['Blake2128Concat']
|
86
|
+
# },
|
87
|
+
# value = {
|
88
|
+
# type: 3,
|
89
|
+
# modifier: 'Default',
|
90
|
+
# callback: '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
91
|
+
# },
|
92
|
+
# ..
|
93
|
+
#
|
94
|
+
# TODO: part of the key is provided, but not all
|
95
|
+
def get_storage(url, pallet_name, item_name, key, value, registry, at = nil)
|
96
|
+
if key
|
97
|
+
if key[:value].nil? || key[:value].empty?
|
98
|
+
# map, but no key's value provided. get all storages under the partial storage key
|
99
|
+
partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name).to_hex
|
100
|
+
get_storages_by_partial_key(
|
101
|
+
url,
|
102
|
+
partial_storage_key,
|
103
|
+
value[:type],
|
104
|
+
value[:modifier] == 'Default' ? value[:fallback] : nil,
|
105
|
+
registry,
|
106
|
+
at
|
107
|
+
)
|
108
|
+
elsif key[:value].length != key[:hashers].length
|
109
|
+
# map with multi parts, but not have all values
|
110
|
+
partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
|
111
|
+
get_storages_by_partial_key(
|
112
|
+
url,
|
113
|
+
partial_storage_key,
|
114
|
+
value[:type],
|
115
|
+
value[:modifier] == 'Default' ? value[:fallback] : nil,
|
116
|
+
registry,
|
117
|
+
at
|
118
|
+
)
|
119
|
+
end
|
120
|
+
else
|
121
|
+
storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
|
122
|
+
data = state_getStorage(url, storage_key, at)
|
123
|
+
StorageHelper.decode_storage(data, value[:type], value[:modifier] == 'Optional', value[:fallback], registry)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_storage2(url, pallet_name, item_name, value_of_key, metadata, at = nil)
|
128
|
+
raise 'Metadata should not be nil' if metadata.nil?
|
129
|
+
|
130
|
+
registry = Metadata.build_registry(metadata)
|
131
|
+
item = Metadata.get_storage_item(
|
132
|
+
pallet_name, item_name, metadata
|
133
|
+
)
|
134
|
+
raise "No such storage item: `#{pallet_name}`.`#{item_name}`" if item.nil?
|
135
|
+
|
136
|
+
modifier = item._get(:modifier) # Default | Optional
|
137
|
+
fallback = item._get(:fallback)
|
138
|
+
type = item._get(:type)
|
139
|
+
|
140
|
+
plain = type._get(:plain)
|
141
|
+
map = type._get(:map)
|
142
|
+
# debug
|
143
|
+
|
144
|
+
key, value =
|
145
|
+
if plain
|
146
|
+
[
|
147
|
+
nil,
|
148
|
+
{ type: plain,
|
149
|
+
modifier: modifier, fallback: fallback }
|
150
|
+
]
|
151
|
+
elsif map
|
152
|
+
[
|
153
|
+
{ value: value_of_key,
|
154
|
+
type: map._get(:key), hashers: map._get(:hashers) },
|
155
|
+
{ type: map._get(:value),
|
156
|
+
modifier: modifier, fallback: fallback }
|
157
|
+
]
|
158
|
+
else
|
159
|
+
raise 'NoSuchStorageType'
|
160
|
+
end
|
161
|
+
get_storage(url, pallet_name, item_name, key, value, registry, at)
|
162
|
+
end
|
163
|
+
|
164
|
+
def to_pascal(str)
|
165
|
+
str.split('_').collect(&:capitalize).join
|
166
|
+
end
|
167
|
+
|
168
|
+
# convert key to byte array
|
169
|
+
def c(key)
|
170
|
+
if key.start_with?('0x')
|
171
|
+
key.to_bytes
|
172
|
+
elsif key.to_i.to_s == key # check if key is a number
|
173
|
+
key.to_i
|
174
|
+
else
|
175
|
+
key
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/lib/codec.rb
CHANGED
@@ -191,9 +191,9 @@ module ScaleRb
|
|
191
191
|
# Decode
|
192
192
|
class << self
|
193
193
|
def decode(type, bytes, registry = {})
|
194
|
-
logger.debug '--------------------------------------------------'
|
195
|
-
debug 'decoding type', type
|
196
|
-
debug 'bytes', bytes&.length
|
194
|
+
# logger.debug '--------------------------------------------------'
|
195
|
+
# debug 'decoding type', type
|
196
|
+
# debug 'bytes', bytes&.length
|
197
197
|
|
198
198
|
if type.instance_of?(String)
|
199
199
|
return decode_bytes(bytes) if bytes?(type) # Bytes
|
@@ -221,8 +221,8 @@ module ScaleRb
|
|
221
221
|
def decode_bytes(bytes)
|
222
222
|
length, remaining_bytes = _do_decode_compact(bytes)
|
223
223
|
value = remaining_bytes[0...length].to_hex
|
224
|
-
debug 'length', length
|
225
|
-
debug 'value', value
|
224
|
+
# debug 'length', length
|
225
|
+
# debug 'value', value
|
226
226
|
[
|
227
227
|
value,
|
228
228
|
remaining_bytes[length..]
|
@@ -238,7 +238,7 @@ module ScaleRb
|
|
238
238
|
else
|
239
239
|
raise InvalidBytesError, 'type: Boolean'
|
240
240
|
end
|
241
|
-
debug 'value', value
|
241
|
+
# debug 'value', value
|
242
242
|
[value, bytes[1..]]
|
243
243
|
end
|
244
244
|
|
@@ -247,8 +247,8 @@ module ScaleRb
|
|
247
247
|
raise NotEnoughBytesError, 'type: String' if remaining_bytes.length < length
|
248
248
|
|
249
249
|
value = remaining_bytes[0...length].to_utf8
|
250
|
-
debug 'byte length', length
|
251
|
-
debug 'value', value.inspect
|
250
|
+
# debug 'byte length', length
|
251
|
+
# debug 'value', value.inspect
|
252
252
|
[
|
253
253
|
value,
|
254
254
|
remaining_bytes[length..]
|
@@ -261,7 +261,7 @@ module ScaleRb
|
|
261
261
|
raise NotEnoughBytesError, "type: #{type}" if bytes.length < byte_length
|
262
262
|
|
263
263
|
value = bytes[0...byte_length].flip.to_int(bit_length)
|
264
|
-
debug 'value', value
|
264
|
+
# debug 'value', value
|
265
265
|
[
|
266
266
|
value,
|
267
267
|
bytes[byte_length..]
|
@@ -274,7 +274,7 @@ module ScaleRb
|
|
274
274
|
raise NotEnoughBytesError, "type: #{type_def}" if bytes.length < byte_length
|
275
275
|
|
276
276
|
value = bytes[0...byte_length].flip.to_uint
|
277
|
-
debug 'value', value
|
277
|
+
# debug 'value', value
|
278
278
|
[
|
279
279
|
value,
|
280
280
|
bytes[byte_length..]
|
@@ -282,9 +282,8 @@ module ScaleRb
|
|
282
282
|
end
|
283
283
|
|
284
284
|
def decode_compact(bytes)
|
285
|
-
|
286
|
-
debug 'value', result[0]
|
287
|
-
result
|
285
|
+
_do_decode_compact(bytes)
|
286
|
+
# debug 'value', result[0]
|
288
287
|
end
|
289
288
|
|
290
289
|
def decode_option(type_def, bytes, registry = {})
|
@@ -304,7 +303,7 @@ module ScaleRb
|
|
304
303
|
def decode_vec(type_def, bytes, registry = {})
|
305
304
|
inner_type = parse_vec(type_def)
|
306
305
|
length, remaining_bytes = _do_decode_compact(bytes)
|
307
|
-
debug 'length', length
|
306
|
+
# debug 'length', length
|
308
307
|
_decode_types([inner_type] * length, remaining_bytes, registry)
|
309
308
|
end
|
310
309
|
|
@@ -331,7 +330,7 @@ module ScaleRb
|
|
331
330
|
raise IndexOutOfRangeError, "type: #{type_def}" if index > items.length - 1
|
332
331
|
|
333
332
|
item = items.to_a[index] # 'name' or [:name, inner_type]
|
334
|
-
debug 'value', item.inspect
|
333
|
+
# debug 'value', item.inspect
|
335
334
|
return [item, bytes[1..]] if item.instance_of?(String)
|
336
335
|
|
337
336
|
value, remaining_bytes = decode(item[1], bytes[1..], registry)
|
@@ -353,9 +352,9 @@ module ScaleRb
|
|
353
352
|
# Encode
|
354
353
|
class << self
|
355
354
|
def encode(type, value, registry = {})
|
356
|
-
logger.debug '--------------------------------------------------'
|
357
|
-
debug 'encoding type', type
|
358
|
-
debug 'value', value
|
355
|
+
# logger.debug '--------------------------------------------------'
|
356
|
+
# debug 'encoding type', type
|
357
|
+
# debug 'value', value
|
359
358
|
|
360
359
|
if type.instance_of?(String)
|
361
360
|
return encode_bytes(value) if bytes?(type)
|
data/lib/scale_rb/version.rb
CHANGED
data/lib/storage_helper.rb
CHANGED
@@ -12,26 +12,26 @@ module StorageHelper
|
|
12
12
|
|
13
13
|
if key && registry
|
14
14
|
|
15
|
-
key_types, key_values =
|
15
|
+
key_types, key_values, key_hashers =
|
16
16
|
if key[:hashers].length == 1
|
17
17
|
[
|
18
18
|
[key[:type]],
|
19
|
-
key[:value]
|
19
|
+
key[:value],
|
20
|
+
key[:hashers]
|
20
21
|
]
|
21
22
|
else
|
22
23
|
[
|
23
|
-
registry[key[:type]]._get(:def)._get(:tuple),
|
24
|
-
key[:value]
|
24
|
+
registry[key[:type]]._get(:def)._get(:tuple).first(key[:value].length),
|
25
|
+
key[:value],
|
26
|
+
key[:hashers].first(key[:value].length)
|
25
27
|
]
|
26
28
|
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
raise "Key's value doesn't match key's type, key's value: #{key_values.inspect}, but key's type: #{key_types.inspect}. Please check your key's value." if key_types.class != key_values.class || key_types.length != key_values.length
|
34
|
-
storage_key + PortableCodec._encode_types_with_hashers(key_types, key_values, registry, key[:hashers])
|
30
|
+
if key_types.class != key_values.class || key_types.length != key_values.length
|
31
|
+
raise "Key's value doesn't match key's type, key's value: #{key_values.inspect}, but key's type: #{key_types.inspect}. Please check your key's value."
|
32
|
+
end
|
33
|
+
|
34
|
+
storage_key + PortableCodec._encode_types_with_hashers(key_types, key_values, registry, key_hashers)
|
35
35
|
else
|
36
36
|
storage_key
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scale_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aki Wu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: blake2b_rs
|
@@ -76,6 +76,8 @@ files:
|
|
76
76
|
- lib/address.rb
|
77
77
|
- lib/client/abstract_ws_client.rb
|
78
78
|
- lib/client/http_client.rb
|
79
|
+
- lib/client/http_client_metadata.rb
|
80
|
+
- lib/client/http_client_storage.rb
|
79
81
|
- lib/client/rpc_request_builder.rb
|
80
82
|
- lib/codec.rb
|
81
83
|
- lib/hasher.rb
|