scale.rb 0.2.17 → 0.2.18

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: 2b7ae809d469d6fb67c8fdf00ad6debf41b6c5f219d7cdf021f408d3368b7367
4
- data.tar.gz: 19c3ea53bcc3bfaeff46735b135bdf985cc9d79830e90e75e9afa279c48d1af9
3
+ metadata.gz: 6c509663910bc3e5dd790fd40e4e0d04ac4f589c44a0253b8b1b353b17687d82
4
+ data.tar.gz: 30249e26671d18d7568c58df2926a5aa071a4ca7b25af443315c8a92a65d292f
5
5
  SHA512:
6
- metadata.gz: 58f4cfe9d7430aff3c263be9e420d9779166f92ed42d9dd2e926238d8e5909073ed2241800123bb084ec513bc8fe1502f235392787d84dd81877ae61d2a54509
7
- data.tar.gz: 27421c1d163fc130194cfd44249cca443f440bf37faca104ca5fc9db7884554d8f5d14bd4378ba583ffa4555be91fe99f4fa2430953824a109ed87f5ec18863b
6
+ metadata.gz: 4ce9f292eeca2be4bc9f2967f9806730bedfd2fc14b4837a6d3cbea2808f62fbadffd31a40e218968ad2bac886338359bb01c164ed9a781186d78f54dbfb7293
7
+ data.tar.gz: 590a67087cdd8fe40717a0ec255bf0c824e807eec1f5f476c856b5002280f7680f0534559648e3ec3470a66194fd9fa141a1b1a277bbebc8dea15cc838027c5c
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- scale.rb (0.2.17)
4
+ scale.rb (0.2.18)
5
5
  base58
6
6
  blake2b_rs (~> 0.1.2)
7
7
  faye-websocket
8
8
  json (~> 2.3.0)
9
+ thor (~> 1.0)
9
10
  xxhash
10
11
 
11
12
  GEM
@@ -15,37 +16,38 @@ GEM
15
16
  blake2b_rs (0.1.2)
16
17
  ffi (= 1.15.0)
17
18
  thermite (~> 0)
18
- coderay (1.1.2)
19
- diff-lcs (1.3)
19
+ coderay (1.1.3)
20
+ diff-lcs (1.4.4)
20
21
  eventmachine (1.2.7)
21
22
  faye-websocket (0.11.0)
22
23
  eventmachine (>= 0.12.0)
23
24
  websocket-driver (>= 0.5.1)
24
25
  ffi (1.15.0)
25
26
  json (2.3.1)
26
- method_source (0.9.2)
27
+ method_source (1.0.0)
27
28
  minitar (0.9)
28
- pry (0.12.2)
29
- coderay (~> 1.1.0)
30
- method_source (~> 0.9.0)
31
- rake (13.0.1)
32
- rspec (3.9.0)
33
- rspec-core (~> 3.9.0)
34
- rspec-expectations (~> 3.9.0)
35
- rspec-mocks (~> 3.9.0)
36
- rspec-core (3.9.0)
37
- rspec-support (~> 3.9.0)
38
- rspec-expectations (3.9.0)
29
+ pry (0.14.0)
30
+ coderay (~> 1.1)
31
+ method_source (~> 1.0)
32
+ rake (13.0.3)
33
+ rspec (3.10.0)
34
+ rspec-core (~> 3.10.0)
35
+ rspec-expectations (~> 3.10.0)
36
+ rspec-mocks (~> 3.10.0)
37
+ rspec-core (3.10.1)
38
+ rspec-support (~> 3.10.0)
39
+ rspec-expectations (3.10.1)
39
40
  diff-lcs (>= 1.2.0, < 2.0)
40
- rspec-support (~> 3.9.0)
41
- rspec-mocks (3.9.0)
41
+ rspec-support (~> 3.10.0)
42
+ rspec-mocks (3.10.2)
42
43
  diff-lcs (>= 1.2.0, < 2.0)
43
- rspec-support (~> 3.9.0)
44
- rspec-support (3.9.0)
44
+ rspec-support (~> 3.10.0)
45
+ rspec-support (3.10.2)
45
46
  thermite (0.13.0)
46
47
  minitar (~> 0.5)
47
48
  rake (>= 10)
48
49
  tomlrb (~> 1.2)
50
+ thor (1.1.0)
49
51
  tomlrb (1.3.0)
50
52
  websocket-driver (0.7.3)
51
53
  websocket-extensions (>= 0.1.0)
data/README.md CHANGED
@@ -19,7 +19,7 @@ Because the feature of ruby 2.6 is used, the ruby version is required to be >= 2
19
19
  Add this line to your application's Gemfile:
20
20
 
21
21
  ```ruby
22
- gem 'scale.rb', '0.2.16'
22
+ gem 'scale.rb', '0.2.18'
23
23
  ```
24
24
 
25
25
  And then execute:
@@ -37,10 +37,22 @@ Or install it yourself as:
37
37
  ```ruby
38
38
  require "scale"
39
39
 
40
+ Scale::TypeRegistry.instance.load # default
41
+ # Scale::TypeRegistry.instance.load spec_name: "pangolin"
42
+ # Scale::TypeRegistry.instance.load spec_name: "kusama"
43
+
44
+ # print hex changes if you set debug to true, default is false
45
+ Scale::Types.debug = true
46
+
40
47
  # decode a compact integer
41
48
  scale_bytes = Scale::Bytes.new("0x1501") # create scale_bytes object from scale encoded hex string
42
49
  o = Scale::Types::Compact.decode(scale_bytes) # use scale type to decode scale_bytes object
43
50
  p o.value # 69
51
+
52
+ #
53
+ type = Scale::Types::get("Vec<U8>")
54
+ o = type.decode(Scale::Bytes.new("0x080001"))
55
+ assert_eq o.value, [Scale::Types::U8.new(0), Scale::Types::U8.new(1)]
44
56
  ```
45
57
 
46
58
  2. encode
@@ -48,8 +60,23 @@ p o.value # 69
48
60
  ```ruby
49
61
  require "scale"
50
62
 
63
+ Scale::TypeRegistry.instance.load
64
+
51
65
  o = Scale::Types::Compact.new(69)
52
66
  p o.encode # "1501"
67
+
68
+ type = Scale::Types::get("Vec<U8>")
69
+ o = type.new([Scale::Types::U8.new(0), Scale::Types::U8.new(1)])
70
+ p o.encode # "080001"
71
+ ```
72
+
73
+ 3. client
74
+ ```ruby
75
+ require "scale"
76
+
77
+ client = SubstrateClient.new "wss://pangolin-rpc.darwinia.network"
78
+ client.get_storage("EthereumRelay", "ConfirmedHeaderParcels", [0])
79
+
53
80
  ```
54
81
  Please go to `spec` dir for more examples.
55
82
 
data/exe/scale ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "thor"
4
+ require "scale"
5
+
6
+ class ScaleCli < Thor
7
+ desc "list-types WS_ENDPOINT ", "list all types in metadata"
8
+ def list_types(ws)
9
+ client = SubstrateClient.new ws
10
+ metadata = client.get_metadata.value.to_human.to_json
11
+ metadata = JSON.parse(metadata)
12
+
13
+ types = []
14
+ metadata["metadata"]["modules"].each do |m|
15
+ if m["storage"]
16
+ m["storage"]["items"].each do |storage|
17
+ type = storage["type"]
18
+ if type["Plain"]
19
+ types << type["Plain"].gsub("\n ", "").gsub("\n", "")
20
+ elsif type["Map"]
21
+ types << type["Map"]["key"].gsub("\n", "")
22
+ types << type["Map"]["value"].gsub("\n", "")
23
+ end
24
+ end
25
+ end
26
+
27
+ if m["calls"]
28
+ m["calls"].each do |call|
29
+ call["args"].each do |arg|
30
+ types << arg["type"].gsub("\n", "")
31
+ end
32
+ end
33
+ end
34
+
35
+ if m["events"]
36
+ m["events"].each do |event|
37
+ event["args"].each do |arg|
38
+ types << arg.gsub("\n", "")
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ types.uniq!
45
+ puts types
46
+ end
47
+ end
48
+
49
+ ScaleCli.start(ARGV)
data/lib/scale.rb CHANGED
@@ -242,12 +242,18 @@ module Scale
242
242
  end
243
243
 
244
244
  module Types
245
+ class << self
246
+ attr_accessor :debug
247
+ end
248
+
245
249
  def self.list
246
250
  TypeRegistry.instance.types
247
251
  end
248
252
 
249
253
  def self.get(type_name)
250
- TypeRegistry.instance.get(type_name)
254
+ type = TypeRegistry.instance.get(type_name)
255
+ raise "Type '#{type_name}' not exist" if type.nil?
256
+ type
251
257
  end
252
258
 
253
259
  def self.constantize(type)
@@ -272,13 +278,32 @@ module Scale
272
278
  type_str = type_strs.first
273
279
  inner_type_str = type_strs.last
274
280
 
275
- if type_str == "Vec" || type_str == "Option"
276
- klass = Class.new do
277
- include Scale::Types.type_of(type_str)
278
- inner_type inner_type_str
281
+ if type_str == "Vec"
282
+ name = "#{type_str}<#{inner_type_str.camelize2}>"
283
+ name = fix(name)
284
+
285
+ if !Scale::Types.const_defined?(name)
286
+ klass = Class.new do
287
+ include Scale::Types::Vec
288
+ inner_type inner_type_str
289
+ end
290
+ Scale::Types.const_set name, klass
291
+ else
292
+ Scale::Types.const_get name
293
+ end
294
+ elsif type_str == "Option"
295
+ name = "#{type_str}<#{inner_type_str.camelize2}>"
296
+ name = fix(name)
297
+
298
+ if !Scale::Types.const_defined?(name)
299
+ klass = Class.new do
300
+ include Scale::Types::Option
301
+ inner_type inner_type_str
302
+ end
303
+ Scale::Types.const_set name, klass
304
+ else
305
+ Scale::Types.const_get name
279
306
  end
280
- name = "#{type_str}<#{inner_type_str.camelize2}>_#{klass.object_id}"
281
- Scale::Types.const_set fix(name), klass
282
307
  else
283
308
  raise "#{type_str} not support inner type: #{type_string}"
284
309
  end
@@ -295,12 +320,17 @@ module Scale
295
320
  type_str.strip.tr(";", ",")
296
321
  end
297
322
 
298
- klass = Class.new do
299
- include Scale::Types::Tuple
300
- inner_types *type_strs
323
+ name = "TupleOf#{type_strs.map(&:camelize2).join("")}"
324
+ name = fix(name)
325
+ if !Scale::Types.const_defined?(name)
326
+ klass = Class.new do
327
+ include Scale::Types::Tuple
328
+ inner_types *type_strs
329
+ end
330
+ Scale::Types.const_set name, klass
331
+ else
332
+ Scale::Types.const_get name
301
333
  end
302
- name = "Tuple_Of_#{type_strs.map(&:camelize2).join("_")}_#{klass.object_id}"
303
- Scale::Types.const_set fix(name), klass
304
334
  else
305
335
  if type_string == "Enum"
306
336
  # TODO: combine values to items
@@ -343,12 +373,20 @@ module Scale
343
373
 
344
374
  end
345
375
 
376
+ # def fix(name)
377
+ # name
378
+ # .gsub("<", "˂").gsub(">", "˃")
379
+ # .gsub("(", "⁽").gsub(")", "⁾")
380
+ # .gsub(" ", "").gsub(",", "‚")
381
+ # .gsub(":", "։")
382
+ # end
383
+
346
384
  def fix(name)
347
385
  name
348
- .gsub("<", "˂").gsub(">", "˃")
349
- .gsub("(", "").gsub(")", "")
350
- .gsub(" ", "").gsub(",", "")
351
- .gsub(":", "։")
386
+ .gsub("<", "").gsub(">", "")
387
+ .gsub("(", "").gsub(")", "")
388
+ .gsub(" ", "").gsub(",", "")
389
+ .gsub(":", "")
352
390
  end
353
391
 
354
392
  def rename(type)
@@ -426,3 +464,5 @@ class ::Hash
426
464
  Hash[h]
427
465
  end
428
466
  end
467
+
468
+ Scale::Types.debug = false
data/lib/scale/base.rb CHANGED
@@ -33,6 +33,17 @@ module Scale
33
33
  @value
34
34
  end
35
35
  end
36
+
37
+ module ClassMethods
38
+ def inherited(child)
39
+ child.const_set(:TYPE_NAME, child.name)
40
+ end
41
+ end
42
+
43
+ def self.included(base)
44
+ base.extend(ClassMethods)
45
+ base.const_set(:TYPE_NAME, base.name)
46
+ end
36
47
  end
37
48
 
38
49
  # value: one of nil, false, true, scale object
@@ -41,19 +52,24 @@ module Scale
41
52
 
42
53
  module ClassMethods
43
54
  def decode(scale_bytes)
55
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
44
56
  byte = scale_bytes.get_next_bytes(1)
45
57
  if byte == [0]
58
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
46
59
  new(nil)
47
60
  elsif byte == [1]
48
61
  if self::INNER_TYPE_STR == "boolean"
62
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
49
63
  new(false)
50
64
  else
51
65
  # big process
52
66
  value = Scale::Types.get(self::INNER_TYPE_STR).decode(scale_bytes)
67
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
53
68
  new(value)
54
69
  end
55
70
  elsif byte == [2]
56
71
  if self::INNER_TYPE_STR == "boolean"
72
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
57
73
  new(true)
58
74
  else
59
75
  raise "bad data"
@@ -89,9 +105,11 @@ module Scale
89
105
 
90
106
  module ClassMethods
91
107
  def decode(scale_bytes)
108
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
92
109
  bytes = scale_bytes.get_next_bytes self::BYTE_LENGTH
93
110
  bit_length = bytes.length.to_i * 8
94
111
  value = bytes.reverse.bytes_to_hex.to_i(16).to_signed(bit_length)
112
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
95
113
  new(value)
96
114
  end
97
115
  end
@@ -117,10 +135,15 @@ module Scale
117
135
  attr_accessor :byte_length
118
136
 
119
137
  def decode(scale_bytes)
138
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
120
139
  bytes = scale_bytes.get_next_bytes self::BYTE_LENGTH
121
140
  bytes_reversed = bytes.reverse
122
141
  hex = bytes_reversed.reduce("0x") { |hex, byte| hex + byte.to_s(16).rjust(2, "0") }
123
- new(hex.to_i(16))
142
+ result = new(hex.to_i(16))
143
+
144
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
145
+
146
+ result
124
147
  end
125
148
  end
126
149
 
@@ -142,9 +165,14 @@ module Scale
142
165
  include SingleValue
143
166
  # new(1.to_u32, U32(69))
144
167
  module ClassMethods
168
+ def inherited(child)
169
+ child.const_set(:TYPE_NAME, child.name)
170
+ end
171
+
145
172
  def decode(scale_bytes)
173
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
146
174
  item_values = self::ITEM_TYPE_STRS.map do |item_type_str|
147
- type = Scale::TypeRegistry.instance.get(item_type_str)
175
+ type = Scale::Types.get(item_type_str)
148
176
  type.decode(scale_bytes)
149
177
  end
150
178
 
@@ -157,6 +185,7 @@ module Scale
157
185
  value.each_pair do |attr, val|
158
186
  result.send "#{attr}=", val
159
187
  end
188
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
160
189
  result
161
190
  end
162
191
 
@@ -177,6 +206,7 @@ module Scale
177
206
 
178
207
  def self.included(base)
179
208
  base.extend ClassMethods
209
+ base.const_set(:TYPE_NAME, base.name)
180
210
  end
181
211
 
182
212
  def encode
@@ -193,9 +223,11 @@ module Scale
193
223
 
194
224
  module ClassMethods
195
225
  def decode(scale_bytes)
226
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
196
227
  values = self::TYPE_STRS.map do |type_str|
197
228
  Scale::Types.get(type_str).decode(scale_bytes)
198
229
  end
230
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
199
231
  new(values)
200
232
  end
201
233
 
@@ -218,6 +250,7 @@ module Scale
218
250
 
219
251
  module ClassMethods
220
252
  def decode(scale_bytes)
253
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
221
254
  index = scale_bytes.get_next_bytes(1)[0]
222
255
  if const_defined? "ITEM_TYPE_STRS"
223
256
  item_type_str = self::ITEM_TYPE_STRS[index]
@@ -226,7 +259,9 @@ module Scale
226
259
  else
227
260
  value = self::VALUES[index]
228
261
  end
229
- new(value)
262
+ result = new(value)
263
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
264
+ result
230
265
  end
231
266
 
232
267
  def items(items)
@@ -279,6 +314,7 @@ module Scale
279
314
 
280
315
  module ClassMethods
281
316
  def decode(scale_bytes, raw = false)
317
+ puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
282
318
  number = Scale::Types::Compact.decode(scale_bytes).value
283
319
  items = []
284
320
  number.times do
@@ -286,6 +322,7 @@ module Scale
286
322
  item = type.decode(scale_bytes)
287
323
  items << item
288
324
  end
325
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
289
326
  raw ? items : new(items)
290
327
  end
291
328
 
@@ -313,10 +350,12 @@ module Scale
313
350
 
314
351
  module ClassMethods
315
352
  def decode(scale_bytes)
353
+ puts " BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
316
354
  value = "Scale::Types::U#{self::BYTE_LENGTH * 8}".constantize2.decode(scale_bytes).value
317
355
  return new [] unless value || value <= 0
318
356
 
319
357
  result = self::ITEMS.select { |_, mask| value & mask > 0 }.keys
358
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
320
359
  new result
321
360
  end
322
361
 
@@ -349,14 +388,17 @@ module Scale
349
388
 
350
389
  module ClassMethods
351
390
  def decode(scale_bytes)
391
+ puts " BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
352
392
  byte_length = self::BYTE_LENGTH
353
393
  raise "#{self.name} byte length is wrong: #{byte_length}" unless %w[2 3 4 8 16 20 32 64 128 256].include?(byte_length.to_s)
354
394
 
355
395
  bytes = scale_bytes.get_next_bytes(byte_length)
356
396
  str = bytes.pack("C*").force_encoding("utf-8")
357
397
  if str.valid_encoding?
398
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
358
399
  new str
359
400
  else
401
+ puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
360
402
  new bytes.bytes_to_hex
361
403
  end
362
404
  end