scale_rb 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
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