scale_rb 0.1.14 → 0.2.0

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.
@@ -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
@@ -2,52 +2,54 @@
2
2
 
3
3
  require 'json'
4
4
 
5
- module RpcRequestBuilder
6
- def build_json_rpc_body(method, params, id)
7
- {
8
- 'id' => id,
9
- 'jsonrpc' => '2.0',
10
- 'method' => method,
11
- 'params' => params.reject(&:nil?)
12
- }.to_json
13
- end
5
+ module ScaleRb
6
+ module RpcRequestBuilder
7
+ def build_json_rpc_body(method, params, id)
8
+ {
9
+ 'id' => id,
10
+ 'jsonrpc' => '2.0',
11
+ 'method' => method,
12
+ 'params' => params.reject(&:nil?)
13
+ }.to_json
14
+ end
14
15
 
15
- def respond_to_missing?(*_args)
16
- true
17
- end
16
+ def respond_to_missing?(*_args)
17
+ true
18
+ end
18
19
 
19
- # example:
20
- # state_getStorage(1, '0x363a..', 563_868)
21
- #
22
- # ==
23
- #
24
- # build_json_rpc_body('state_getStorage', ['0x363a..', 563_868], 1)
25
- def method_missing(method, *args)
26
- build_json_rpc_body(method, args[1..], args[0])
27
- end
20
+ # example:
21
+ # state_getStorage(1, '0x363a..', 563_868)
22
+ #
23
+ # ==
24
+ #
25
+ # build_json_rpc_body('state_getStorage', ['0x363a..', 563_868], 1)
26
+ def method_missing(method, *args)
27
+ build_json_rpc_body(method, args[1..], args[0])
28
+ end
28
29
 
29
- ###################################
30
- # derived functions
31
- ###################################
32
- def derived_state_get_storage(rpc_id, pallet_name, item_name, key = nil, registry = nil)
33
- storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
34
- state_getStorage(rpc_id, [storage_key])
35
- end
30
+ ###################################
31
+ # derived functions
32
+ ###################################
33
+ def derived_state_get_storage(rpc_id, pallet_name, item_name, key = nil, registry = nil)
34
+ storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry)._to_hex
35
+ state_getStorage(rpc_id, [storage_key])
36
+ end
36
37
 
37
- def derived_state_subscribe_storage(rpc_id, pallet_name, item_name, key = nil, registry = nil)
38
- storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
39
- state_subscribeStorage(rpc_id, [storage_key])
40
- end
38
+ def derived_state_subscribe_storage(rpc_id, pallet_name, item_name, key = nil, registry = nil)
39
+ storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry)._to_hex
40
+ state_subscribeStorage(rpc_id, [storage_key])
41
+ end
41
42
 
42
- def derived_eth_call(rpc_id, to, data, at = nil)
43
- eth_call(
44
- rpc_id,
45
- [
46
- {
47
- 'from' => nil, 'to' => to, 'data' => data
48
- },
49
- at
50
- ]
51
- )
43
+ def derived_eth_call(rpc_id, to, data, at = nil)
44
+ eth_call(
45
+ rpc_id,
46
+ [
47
+ {
48
+ 'from' => nil, 'to' => to, 'data' => data
49
+ },
50
+ at
51
+ ]
52
+ )
53
+ end
52
54
  end
53
55
  end
data/lib/codec.rb CHANGED
@@ -145,12 +145,12 @@ module ScaleRb
145
145
  when 0
146
146
  [bytes[0] >> 2, bytes[1..]]
147
147
  when 1
148
- [bytes[0..1].flip.to_uint >> 2, bytes[2..]]
148
+ [bytes[0..1]._flip._to_uint >> 2, bytes[2..]]
149
149
  when 2
150
- [bytes[0..3].flip.to_uint >> 2, bytes[4..]]
150
+ [bytes[0..3]._flip._to_uint >> 2, bytes[4..]]
151
151
  when 3
152
152
  length = 4 + (bytes[0] >> 2)
153
- [bytes[1..length].flip.to_uint, bytes[length + 1..]]
153
+ [bytes[1..length]._flip._to_uint, bytes[length + 1..]]
154
154
  else
155
155
  raise Unreachable, 'type: Compact'
156
156
  end
@@ -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
@@ -220,9 +220,9 @@ module ScaleRb
220
220
 
221
221
  def decode_bytes(bytes)
222
222
  length, remaining_bytes = _do_decode_compact(bytes)
223
- value = remaining_bytes[0...length].to_hex
224
- debug 'length', length
225
- debug 'value', value
223
+ value = remaining_bytes[0...length]._to_hex
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
 
@@ -246,9 +246,9 @@ module ScaleRb
246
246
  length, remaining_bytes = _do_decode_compact(bytes)
247
247
  raise NotEnoughBytesError, 'type: String' if remaining_bytes.length < length
248
248
 
249
- value = remaining_bytes[0...length].to_utf8
250
- debug 'byte length', length
251
- debug 'value', value.inspect
249
+ value = remaining_bytes[0...length]._to_utf8
250
+ # debug 'byte length', length
251
+ # debug 'value', value.inspect
252
252
  [
253
253
  value,
254
254
  remaining_bytes[length..]
@@ -260,8 +260,8 @@ module ScaleRb
260
260
  byte_length = bit_length / 8
261
261
  raise NotEnoughBytesError, "type: #{type}" if bytes.length < byte_length
262
262
 
263
- value = bytes[0...byte_length].flip.to_int(bit_length)
264
- debug 'value', value
263
+ value = bytes[0...byte_length]._flip._to_int(bit_length)
264
+ # debug 'value', value
265
265
  [
266
266
  value,
267
267
  bytes[byte_length..]
@@ -273,8 +273,8 @@ module ScaleRb
273
273
  byte_length = bit_length / 8
274
274
  raise NotEnoughBytesError, "type: #{type_def}" if bytes.length < byte_length
275
275
 
276
- value = bytes[0...byte_length].flip.to_uint
277
- debug 'value', value
276
+ value = bytes[0...byte_length]._flip._to_uint
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
- result = _do_decode_compact(bytes)
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)
@@ -397,16 +396,16 @@ module ScaleRb
397
396
 
398
397
  def encode_compact(value)
399
398
  return [value << 2] if (value >= 0) && (value < 64)
400
- return ((value << 2) + 1).to_bytes.flip if value < 2**14
401
- return ((value << 2) + 2).to_bytes.flip if value < 2**30
399
+ return ((value << 2) + 1)._to_bytes._flip if value < 2**14
400
+ return ((value << 2) + 2)._to_bytes._flip if value < 2**30
402
401
 
403
- bytes = value.to_bytes.flip
402
+ bytes = value._to_bytes._flip
404
403
  [(((bytes.length - 4) << 2) + 3)] + bytes
405
404
  end
406
405
 
407
406
  def encode_uint(type, value)
408
407
  bit_length = type[1..].to_i
409
- value.to_bytes(bit_length).flip
408
+ value._to_bytes(bit_length)._flip
410
409
  end
411
410
 
412
411
  def encode_option(type, value, registry = {})
data/lib/hasher.rb CHANGED
@@ -3,52 +3,54 @@
3
3
  require 'xxhash'
4
4
  require 'blake2b'
5
5
 
6
- module Hasher
7
- class << self
8
- # params:
9
- # hasher: 'Identity' | 'Twox64Concat' | 'Blake2128Concat'
10
- # bytes: u8 array
11
- # return: u8 array
12
- def apply_hasher(hasher, bytes)
13
- function_name = hasher.gsub('_', '').underscore
14
- Hasher.send(function_name, bytes)
6
+ module ScaleRb
7
+ module Hasher
8
+ class << self
9
+ # params:
10
+ # hasher: 'Identity' | 'Twox64Concat' | 'Blake2128Concat'
11
+ # bytes: u8 array
12
+ # return: u8 array
13
+ def apply_hasher(hasher, bytes)
14
+ function_name = hasher.gsub('_', '')._underscore
15
+ Hasher.send(function_name, bytes)
16
+ end
15
17
  end
16
- end
17
18
 
18
- class << self
19
- def identity(bytes)
20
- bytes
21
- end
19
+ class << self
20
+ def identity(bytes)
21
+ bytes
22
+ end
22
23
 
23
- def twox64_concat(bytes)
24
- data = bytes.to_utf8
25
- twox64(data) + bytes
26
- end
24
+ def twox64_concat(bytes)
25
+ data = bytes._to_utf8
26
+ twox64(data) + bytes
27
+ end
27
28
 
28
- def blake2128_concat(bytes)
29
- blake2_128(bytes) + bytes
30
- end
29
+ def blake2128_concat(bytes)
30
+ blake2_128(bytes) + bytes
31
+ end
31
32
 
32
- def twox64(str)
33
- result = XXhash.xxh64 str, 0
34
- result.to_bytes.reverse
35
- end
33
+ def twox64(str)
34
+ result = XXhash.xxh64 str, 0
35
+ result._to_bytes.reverse
36
+ end
36
37
 
37
- def twox128(str)
38
- bytes = []
39
- 2.times do |i|
40
- result = XXhash.xxh64 str, i
41
- bytes += result.to_bytes.reverse
38
+ def twox128(str)
39
+ bytes = []
40
+ 2.times do |i|
41
+ result = XXhash.xxh64 str, i
42
+ bytes += result._to_bytes.reverse
43
+ end
44
+ bytes
42
45
  end
43
- bytes
44
- end
45
46
 
46
- def blake2_128(bytes)
47
- Blake2b.hex(bytes, 16).to_bytes
48
- end
47
+ def blake2_128(bytes)
48
+ Blake2b.hex(bytes, 16)._to_bytes
49
+ end
49
50
 
50
- def blake2_256(bytes)
51
- Blake2b.hex(bytes, 32).to_bytes
51
+ def blake2_256(bytes)
52
+ Blake2b.hex(bytes, 32)._to_bytes
53
+ end
52
54
  end
53
55
  end
54
56
  end