scale.rb 0.2.17 → 0.2.18

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: 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