scale_rb 0.1.14 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82a0911194368a4fcefec7a414694346f087c0ded749d3865f6732f27c8afef0
4
- data.tar.gz: 14b34a748f835c527726ebd42440cced5ed8b5c0d954cb15c41e288ce3e5aff6
3
+ metadata.gz: d49c850c60bd8f6807d0c04995d3b8a5262f63dc627b585e683d774e91ed96ab
4
+ data.tar.gz: adbba1bbba8cf9bbf3f559893a2b69f90d94a41a259db713f1a7db6dcb83b29f
5
5
  SHA512:
6
- metadata.gz: 805efca604cc93794b5c1d4ee3dd1785d74d6a049b55f0ecc0503c85869c2759a37380b6735b8ecf874b6b33b31492f7b203870b7b414758740545821f98db19
7
- data.tar.gz: d5f577ec96adf7a51ef7044b0d5f8bc874e3a12daf66e3cc743677a6a095ddda909267b941dd15a06646dc941caeabe810fd960140c1c94261d173796ee40b9d
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.14)
4
+ scale_rb (0.1.15)
5
5
  base58
6
6
  blake2b_rs (~> 0.1.4)
7
7
  xxhash
@@ -4,6 +4,7 @@ require 'uri'
4
4
  require 'net/http'
5
5
  require 'json'
6
6
  require_relative './http_client_metadata'
7
+ require_relative './http_client_storage'
7
8
 
8
9
  # TODO: method_name = cmd.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
9
10
  module ScaleRb
@@ -60,176 +61,6 @@ module ScaleRb
60
61
  result = json_rpc_call(url, 'rpc_methods', [])
61
62
  result['methods']
62
63
  end
63
-
64
- def get_metadata(url, at = nil)
65
- hex = state_getMetadata(url, at)
66
- Metadata.decode_metadata(hex.strip.to_bytes)
67
- end
68
-
69
- def query_storage_at(url, storage_keys, type_id, default, registry, at = nil)
70
- result = state_queryStorageAt(url, storage_keys, at)
71
- result.map do |item|
72
- item['changes'].map do |change|
73
- storage_key = change[0]
74
- data = change[1] || default
75
- storage = data.nil? ? nil : PortableCodec.decode(type_id, data.to_bytes, registry)[0]
76
- { storage_key: storage_key, storage: storage }
77
- end
78
- end.flatten
79
- end
80
-
81
- def get_storage_keys_by_partial_key(url, partial_storage_key, start_key = nil, at = nil)
82
- storage_keys = state_getKeysPaged(url, partial_storage_key, 1000, start_key, at)
83
- if storage_keys.length == 1000
84
- storage_keys + get_storage_keys_by_partial_key(url, partial_storage_key, storage_keys.last, at)
85
- else
86
- storage_keys
87
- end
88
- end
89
-
90
- def get_storages_by_partial_key(url, partial_storage_key, type_id_of_value, default, registry, at = nil)
91
- storage_keys = get_storage_keys_by_partial_key(url, partial_storage_key, partial_storage_key, at)
92
- storage_keys.each_slice(250).map do |slice|
93
- query_storage_at(
94
- url,
95
- slice,
96
- type_id_of_value,
97
- default,
98
- registry,
99
- at
100
- )
101
- end.flatten
102
- end
103
-
104
- # 1. Plain
105
- # key: nil
106
- # value: { type: 3, modifier: 'Default', callback: '' }
107
- #
108
- # 2. Map
109
- # key: { value: value, type: 0, hashers: ['Blake2128Concat'] }
110
- # value: { type: 3, modifier: 'Default', callback: '' }
111
- #
112
- # 3. Map, but key.value is nil
113
- # key: { value: nil, type: 0, hashers: ['Blake2128Concat'] }
114
- # value: { type: 3, modifier: 'Default', callback: '' }
115
- #
116
- # example:
117
- # 'System',
118
- # 'Account',
119
- # key = {
120
- # value: [['0x724d50824542b56f422588421643c4a162b90b5416ef063f2266a1eae6651641'.to_bytes]], # [AccountId]
121
- # type: 0,
122
- # hashers: ['Blake2128Concat']
123
- # },
124
- # value = {
125
- # type: 3,
126
- # modifier: 'Default',
127
- # callback: '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
128
- # },
129
- # ..
130
- #
131
- # TODO: part of the key is provided, but not all
132
- def get_storage(url, pallet_name, item_name, key, value, registry, at = nil)
133
- if key
134
- if key[:value].nil? || key[:value].empty?
135
- # map, but no key's value provided. get all storages under the partial storage key
136
- partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name).to_hex
137
- get_storages_by_partial_key(
138
- url,
139
- partial_storage_key,
140
- value[:type],
141
- value[:modifier] == 'Default' ? value[:fallback] : nil,
142
- registry,
143
- at
144
- )
145
- elsif key[:value].length != key[:hashers].length
146
- # map with multi part, but only provide part value
147
- partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
148
- get_storages_by_partial_key(
149
- url,
150
- partial_storage_key,
151
- value[:type],
152
- value[:modifier] == 'Default' ? value[:fallback] : nil,
153
- registry,
154
- at
155
- )
156
- end
157
- else
158
- storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
159
- data = state_getStorage(url, storage_key, at)
160
- StorageHelper.decode_storage(data, value[:type], value[:modifier] == 'Optional', value[:fallback], registry)
161
- end
162
- end
163
-
164
- def get_storage2(url, pallet_name, item_name, value_of_key, metadata, at = nil)
165
- raise 'Metadata should not be nil' if metadata.nil?
166
-
167
- registry = Metadata.build_registry(metadata)
168
- item = Metadata.get_storage_item(pallet_name, item_name, metadata)
169
- raise "No such storage item: `#{pallet_name}`.`#{item_name}`" if item.nil?
170
-
171
- modifier = item._get(:modifier) # Default | Optional
172
- fallback = item._get(:fallback)
173
- type = item._get(:type)
174
-
175
- plain = type._get(:plain)
176
- map = type._get(:map)
177
- # debug
178
-
179
- key, value =
180
- if plain
181
- [
182
- nil,
183
- { type: plain, modifier: modifier, fallback: fallback }
184
- ]
185
- elsif map
186
- [
187
- { value: value_of_key, type: map._get(:key), hashers: map._get(:hashers) },
188
- { type: map._get(:value), modifier: modifier, fallback: fallback }
189
- ]
190
- else
191
- raise 'NoSuchStorageType'
192
- end
193
- get_storage(url, pallet_name, item_name, key, value, registry, at)
194
- end
195
-
196
- # get_storage3 is a more ruby style function
197
- #
198
- # pallet_name and storage_name is pascal style like 'darwinia_staking'
199
- def get_storage3(url, metadata, pallet_name, storage_name, key_part1: nil, key_part2: nil, at: nil)
200
- pallet_name = to_pascal pallet_name
201
- storage_name = to_pascal storage_name
202
- ScaleRb.logger.debug "#{pallet_name}.#{storage_name}(#{[key_part1, key_part2].compact.join(', ')})"
203
-
204
- key = [key_part1, key_part2].compact.map { |part_of_key| c(part_of_key) }
205
- ScaleRb.logger.debug "converted key: #{key}"
206
-
207
- get_storage2(
208
- url,
209
- pallet_name,
210
- storage_name,
211
- key,
212
- metadata,
213
- at
214
- )
215
- end
216
-
217
- private
218
-
219
- def to_pascal(str)
220
- str.split('_').collect(&:capitalize).join
221
- end
222
-
223
- # convert key to byte array
224
- def c(key)
225
- if key.start_with?('0x')
226
- key.to_bytes
227
- elsif key.to_i.to_s == key # check if key is a number
228
- key.to_i
229
- else
230
- key
231
- end
232
- end
233
64
  end
234
65
  end
235
66
  end
@@ -4,14 +4,16 @@ require 'fileutils'
4
4
  module ScaleRb
5
5
  module HttpClient
6
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
+
7
12
  # cached version of get_metadata
8
13
  # get metadata from cache first
9
- def get_metadata_cached(url, at: nil, dir: File.join(Dir.pwd, 'metadata'))
10
- # if at
11
- # require_block_hash_correct(url, at)
12
- # else
13
- # at = ScaleRb::HttpClient.chain_getFinalizedHead(url)
14
- # end
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
+
15
17
  at = ScaleRb::HttpClient.chain_getFinalizedHead(url) if at.nil?
16
18
  spec_name, spec_version = get_spec(url, at)
17
19
 
@@ -27,7 +29,7 @@ module ScaleRb
27
29
  metadata = ScaleRb::HttpClient.get_metadata(url, at)
28
30
 
29
31
  # cache it
30
- puts "caching metadata `#{spec_name}_#{spec_version}.json`"
32
+ ScaleRb.logger.debug "caching metadata `#{spec_name}_#{spec_version}.json`"
31
33
  save_metadata_to_file(
32
34
  spec_name: spec_name,
33
35
  spec_version: spec_version,
@@ -54,7 +56,7 @@ module ScaleRb
54
56
  file_path = File.join(dir, "#{spec_name}_#{spec_version}.json")
55
57
  return unless File.exist?(file_path)
56
58
 
57
- puts "found metadata `#{spec_name}_#{spec_version}.json` in cache"
59
+ ScaleRb.logger.debug "found metadata `#{spec_name}_#{spec_version}.json` in cache"
58
60
  JSON.parse(File.read(file_path))
59
61
  end
60
62
 
@@ -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
- 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)
@@ -1,3 +1,3 @@
1
1
  module ScaleRb
2
- VERSION = '0.1.14'
2
+ VERSION = '0.1.15'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scale_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aki Wu
@@ -77,6 +77,7 @@ files:
77
77
  - lib/client/abstract_ws_client.rb
78
78
  - lib/client/http_client.rb
79
79
  - lib/client/http_client_metadata.rb
80
+ - lib/client/http_client_storage.rb
80
81
  - lib/client/rpc_request_builder.rb
81
82
  - lib/codec.rb
82
83
  - lib/hasher.rb