scale.rb 0.2.18 → 0.3.2

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.
data/lib/scale/block.rb CHANGED
@@ -2,11 +2,11 @@ module Scale
2
2
  module Types
3
3
 
4
4
  class Extrinsic
5
- include SingleValue
5
+ include Base
6
6
  # attr_accessor :address, :signature, :nonce, :era, :extrinsic_hash, :call_index, :params_raw, :params
7
7
 
8
- def self.generate_hash(data)
9
- Blake2b.hex data, Blake2b::Key.none, 32
8
+ def self.generate_hash(bytes)
9
+ Crypto.blake2_256 bytes
10
10
  end
11
11
 
12
12
  def self.decode(scale_bytes)
@@ -61,10 +61,10 @@ module Scale
61
61
 
62
62
  if contains_transaction
63
63
  result[:address] = Scale::Types.get("Address").decode(scale_bytes).value
64
- result[:signature] = scale::types.get("MultiSignature").decode(scale_bytes).value
65
- result[:era] = scale::types.get("era").decode(scale_bytes).value
66
- result[:nonce] = scale::types.get("compact").decode(scale_bytes).value
67
- result[:tip] = scale::types.get("compact").decode(scale_bytes).value
64
+ result[:signature] = Scale::Types.get("MultiSignature").decode(scale_bytes).value
65
+ result[:era] = Scale::Types.get("Era").decode(scale_bytes).value
66
+ result[:nonce] = Scale::Types.get("Compact").decode(scale_bytes).value
67
+ result[:tip] = Scale::Types.get("Compact").decode(scale_bytes).value
68
68
  result[:extrinsic_hash] = generate_hash(scale_bytes.bytes)
69
69
  end
70
70
  result[:call_index] = scale_bytes.get_next_bytes(2).bytes_to_hex[2..]
@@ -116,7 +116,7 @@ module Scale
116
116
  end
117
117
 
118
118
  class EventRecords
119
- include SingleValue
119
+ include Base
120
120
 
121
121
  def self.decode(scale_bytes)
122
122
 
@@ -129,7 +129,7 @@ module Scale
129
129
  end
130
130
 
131
131
  class EventRecord
132
- include SingleValue
132
+ include Base
133
133
 
134
134
  def self.decode(scale_bytes)
135
135
  metadata = Scale::TypeRegistry.instance.metadata.value
@@ -211,7 +211,7 @@ module Scale
211
211
 
212
212
  class LogDigest
213
213
  include Enum
214
- items %w[Other AuthoritiesChange ChangesTrieRoot SealV0 Consensus Seal PreRuntime]
214
+ inner_types *%w[Other AuthoritiesChange ChangesTrieRoot SealV0 Consensus Seal PreRuntime]
215
215
  end
216
216
 
217
217
  end
data/lib/scale/trie.rb CHANGED
@@ -2,7 +2,7 @@ module Scale
2
2
  module Types
3
3
 
4
4
  class TrieNode
5
- include SingleValue
5
+ include Base
6
6
  EMPTY = 0
7
7
  NIBBLE_PER_BYTE = 2
8
8
  BITMAP_LENGTH = 2
data/lib/scale/types.rb CHANGED
@@ -2,7 +2,7 @@ module Scale
2
2
  module Types
3
3
 
4
4
  class Bool
5
- include SingleValue
5
+ include Base
6
6
  BYTES_LENGTH = 1
7
7
 
8
8
  def self.decode(scale_bytes)
@@ -10,10 +10,10 @@ module Scale
10
10
  bytes = scale_bytes.get_next_bytes(self::BYTES_LENGTH)
11
11
  if bytes == [0]
12
12
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
13
- Bool.new(false)
13
+ new(false)
14
14
  elsif bytes == [1]
15
15
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
16
- Bool.new(true)
16
+ new(true)
17
17
  else
18
18
  raise "Bad data"
19
19
  end
@@ -24,6 +24,35 @@ module Scale
24
24
  end
25
25
  end
26
26
 
27
+ class OptionBool
28
+ include Base
29
+ def self.decode(scale_bytes)
30
+ byte = scale_bytes.get_next_bytes(1)[0]
31
+ value = if byte == 0x00
32
+ nil
33
+ elsif byte == 0x01
34
+ true
35
+ elsif byte == 0x02
36
+ false
37
+ else
38
+ raise BadDataError.new("Bad scale data for OptionBool #{byte.to_s(16)}")
39
+ end
40
+ new(value)
41
+ end
42
+
43
+ def encode
44
+ if value.nil?
45
+ "00"
46
+ elsif value === true
47
+ "01"
48
+ elsif value === false
49
+ "02"
50
+ else
51
+ raise WrongValueError.new("OptionBool can not have value other than `nil`, `true`, `false`")
52
+ end
53
+ end
54
+ end
55
+
27
56
  class U8
28
57
  include FixedWidthUInt
29
58
  BYTE_LENGTH = 1
@@ -54,6 +83,11 @@ module Scale
54
83
  BYTE_LENGTH = 32
55
84
  end
56
85
 
86
+ class U512
87
+ include FixedWidthUInt
88
+ BYTE_LENGTH = 64
89
+ end
90
+
57
91
  class I8
58
92
  include FixedWidthInt
59
93
  BYTE_LENGTH = 1
@@ -80,7 +114,7 @@ module Scale
80
114
  end
81
115
 
82
116
  class Compact
83
- include SingleValue
117
+ include Base
84
118
 
85
119
  def self.decode(scale_bytes)
86
120
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
@@ -118,7 +152,7 @@ module Scale
118
152
  end
119
153
 
120
154
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
121
- Compact.new(value)
155
+ new(value)
122
156
  end
123
157
 
124
158
  def encode
@@ -143,7 +177,7 @@ module Scale
143
177
  end
144
178
 
145
179
  class Bytes
146
- include SingleValue
180
+ include Base
147
181
 
148
182
  def self.decode(scale_bytes)
149
183
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
@@ -153,12 +187,13 @@ module Scale
153
187
  # [67, 97, 102, 195, 169].pack('C*').force_encoding('utf-8')
154
188
  # => "Café"
155
189
  str = bytes.pack("C*").force_encoding("utf-8")
156
- if str.valid_encoding?
190
+ # TODO: ?
191
+ if (not str.include?("\u0000")) && str.valid_encoding?
157
192
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
158
- Bytes.new str
193
+ new str
159
194
  else
160
195
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
161
- Bytes.new bytes.bytes_to_hex
196
+ new bytes.bytes_to_hex
162
197
  end
163
198
  end
164
199
 
@@ -176,35 +211,40 @@ module Scale
176
211
  end
177
212
 
178
213
  class Hex
179
- include SingleValue
214
+ include Base
180
215
 
181
216
  def self.decode(scale_bytes)
182
217
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
183
218
  length = Scale::Types::Compact.decode(scale_bytes).value
184
219
  hex_string = scale_bytes.get_next_bytes(length).bytes_to_hex
185
220
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
186
- Hex.new(hex_string)
221
+ new(hex_string)
222
+ end
223
+
224
+ def encode
225
+ length = Compact.new((value.length - 2)/2).encode
226
+ "#{length}#{value[2..]}"
187
227
  end
188
228
  end
189
229
 
190
230
  class String
191
- include SingleValue
231
+ include Base
192
232
  def self.decode(scale_bytes)
193
233
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
194
234
  length = Scale::Types::Compact.decode(scale_bytes).value
195
235
  bytes = scale_bytes.get_next_bytes(length)
196
236
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
197
- String.new bytes.pack("C*").force_encoding("utf-8")
237
+ new bytes.pack("C*").force_encoding("utf-8")
198
238
  end
199
239
  end
200
240
 
201
241
  class H160
202
- include SingleValue
242
+ include Base
203
243
  def self.decode(scale_bytes)
204
244
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
205
245
  bytes = scale_bytes.get_next_bytes(20)
206
246
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
207
- H160.new(bytes.bytes_to_hex)
247
+ new(bytes.bytes_to_hex)
208
248
  end
209
249
 
210
250
  def encode
@@ -214,12 +254,12 @@ module Scale
214
254
  end
215
255
 
216
256
  class H256
217
- include SingleValue
257
+ include Base
218
258
  def self.decode(scale_bytes)
219
259
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
220
260
  bytes = scale_bytes.get_next_bytes(32)
221
261
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
222
- H256.new(bytes.bytes_to_hex)
262
+ new(bytes.bytes_to_hex)
223
263
  end
224
264
 
225
265
  def encode
@@ -229,12 +269,12 @@ module Scale
229
269
  end
230
270
 
231
271
  class H512
232
- include SingleValue
272
+ include Base
233
273
  def self.decode(scale_bytes)
234
274
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
235
275
  bytes = scale_bytes.get_next_bytes(64)
236
276
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
237
- H512.new(bytes.bytes_to_hex)
277
+ new(bytes.bytes_to_hex)
238
278
  end
239
279
 
240
280
  def encode
@@ -244,7 +284,7 @@ module Scale
244
284
  end
245
285
 
246
286
  class GenericAddress
247
- include SingleValue
287
+ include Base
248
288
 
249
289
  # https://github.com/paritytech/substrate/wiki/External-Address-Format-(SS58)
250
290
  # base58encode ( concat ( <address-type>, <address>, <checksum> ) )
@@ -260,7 +300,7 @@ module Scale
260
300
  account_length = [account_length].bytes_to_hex
261
301
 
262
302
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
263
- Address.new({
303
+ new({
264
304
  account_id: account_id,
265
305
  account_length: account_length
266
306
  })
@@ -279,7 +319,7 @@ module Scale
279
319
  account_length = [account_length].bytes_to_hex
280
320
 
281
321
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
282
- Address.new({
322
+ new({
283
323
  account_index: account_index,
284
324
  account_length: account_length
285
325
  })
@@ -302,7 +342,7 @@ module Scale
302
342
  class AccountIdAddress < GenericAddress
303
343
  def self.decode(scale_bytes)
304
344
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
305
- result = AccountIdAddress.new({
345
+ result = new({
306
346
  account_id: AccountId.decode(scale_bytes).value,
307
347
  account_length: "0xff"
308
348
  })
@@ -316,6 +356,17 @@ module Scale
316
356
  end
317
357
  end
318
358
 
359
+ class GenericMultiAddress
360
+ include Enum
361
+ items(
362
+ Id: "AccountId",
363
+ Index: "Compact",
364
+ Raw: "Hex",
365
+ Address32: "H256",
366
+ Address20: "H160"
367
+ )
368
+ end
369
+
319
370
  class AccountId < H256; end
320
371
 
321
372
  class Balance < U128; end
@@ -327,14 +378,14 @@ module Scale
327
378
  class AccountIndex < U32; end
328
379
 
329
380
  class Era
330
- include SingleValue
381
+ include Base
331
382
  def self.decode(scale_bytes)
332
383
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
333
384
  byte = scale_bytes.get_next_bytes(1).bytes_to_hex
334
385
  result = if byte == "0x00"
335
- Era.new byte
386
+ new byte
336
387
  else
337
- Era.new byte + scale_bytes.get_next_bytes(1).bytes_to_hex()[2..]
388
+ new byte + scale_bytes.get_next_bytes(1).bytes_to_hex()[2..]
338
389
  end
339
390
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
340
391
  result
@@ -346,7 +397,7 @@ module Scale
346
397
  class Moment < U64; end
347
398
 
348
399
  class CompactMoment
349
- include SingleValue
400
+ include Base
350
401
  def self.decode(scale_bytes)
351
402
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
352
403
  value = Compact.decode(scale_bytes).value
@@ -355,7 +406,7 @@ module Scale
355
406
  end
356
407
 
357
408
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
358
- CompactMoment.new Time.at(value).strftime("%F %T")
409
+ new Time.at(value).strftime("%F %T")
359
410
  end
360
411
  end
361
412
 
@@ -459,9 +510,9 @@ module Scale
459
510
  end
460
511
 
461
512
  class Null
462
- include SingleValue
513
+ include Base
463
514
  def self.decode(scale_bytes)
464
- Null.new nil
515
+ new nil
465
516
  end
466
517
 
467
518
  def encode
@@ -652,20 +703,20 @@ module Scale
652
703
  include Struct
653
704
  items(
654
705
  id: "VecU8Length8",
655
- amount: "Balance",
706
+ amount: "Scale::Types::Balance",
656
707
  until: "U32",
657
- reasons: "WithdrawReasons"
708
+ reasons: "Scale::Types::WithdrawReasons"
658
709
  )
659
710
  end
660
711
 
661
712
  class EthereumAddress
662
- include SingleValue
713
+ include Base
663
714
 
664
715
  def self.decode(scale_bytes)
665
716
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
666
717
  bytes = scale_bytes.get_next_bytes(20)
667
718
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
668
- EthereumAddress.new(bytes.bytes_to_hex)
719
+ new(bytes.bytes_to_hex)
669
720
  end
670
721
 
671
722
  def encode
@@ -678,12 +729,12 @@ module Scale
678
729
  end
679
730
 
680
731
  class EcdsaSignature
681
- include SingleValue
732
+ include Base
682
733
 
683
734
  def self.decode(scale_bytes)
684
735
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
685
736
  bytes = scale_bytes.get_next_bytes(65)
686
- EcdsaSignature.new(bytes.bytes_to_hex)
737
+ new(bytes.bytes_to_hex)
687
738
  puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
688
739
  end
689
740
 
@@ -790,7 +841,7 @@ module Scale
790
841
  end
791
842
 
792
843
  class VoteOutcome
793
- include SingleValue
844
+ include Base
794
845
  def self.decode(scale_bytes)
795
846
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
796
847
  result = new(scale_bytes.get_next_bytes(32))
@@ -834,7 +885,7 @@ module Scale
834
885
  end
835
886
 
836
887
  class BoxProposal
837
- include SingleValue
888
+ include Base
838
889
 
839
890
  def self.decode(scale_bytes, metadata, chain_spec)
840
891
  puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
@@ -872,7 +923,7 @@ module Scale
872
923
  end
873
924
 
874
925
  class VecH512Length2
875
- include SingleValue
926
+ include Base
876
927
 
877
928
  def self.decode(scale_bytes)
878
929
  end
@@ -885,7 +936,7 @@ module Scale
885
936
  end
886
937
 
887
938
  class GenericBlock
888
- include SingleValue
939
+ include Base
889
940
 
890
941
  def self.decode(scale_bytes)
891
942
  end
data/lib/scale/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Scale
2
- VERSION = "0.2.18".freeze
2
+ VERSION = "0.3.2".freeze
3
3
  end
data/lib/scale.rb CHANGED
@@ -5,6 +5,11 @@ require "common"
5
5
  require "json"
6
6
  require "singleton"
7
7
 
8
+ require "scale_bytes"
9
+
10
+ require "type_registry"
11
+ require "type_builder"
12
+
8
13
  require "scale/base"
9
14
  require "scale/types"
10
15
  require "scale/block"
@@ -24,399 +29,36 @@ require "metadata/metadata_v9"
24
29
  require "metadata/metadata_v10"
25
30
  require "metadata/metadata_v11"
26
31
  require "metadata/metadata_v12"
32
+ require "metadata/metadata_v13"
27
33
 
28
34
  require "substrate_client"
29
35
  require "logger"
30
36
  require "helper"
31
37
 
32
- class String
33
- def upcase_first
34
- self.sub(/\S/, &:upcase)
35
- end
36
-
37
- def camelize2
38
- self.split('_').collect(&:upcase_first).join
39
- end
40
-
41
- def underscore2
42
- self.gsub(/::/, '/').
43
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
44
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
45
- tr("-", "_").
46
- downcase
47
- end
48
- end
49
-
50
38
  module Scale
51
- class Error < StandardError; end
52
-
53
- class TypeRegistry
54
- include Singleton
55
-
56
- # init by load, and will not change
57
- attr_reader :spec_name, :types
58
- attr_reader :versioning, :custom_types # optional
59
-
60
- # will change by different spec version
61
- attr_accessor :spec_version # optional
62
- attr_accessor :metadata
63
-
64
- def load(spec_name: nil, custom_types: nil)
65
- @spec_name = nil
66
- @types = nil
67
- @versioning = nil
68
- @custom_types = nil
69
-
70
- default_types, _, _ = load_chain_spec_types("default")
71
-
72
- if spec_name
73
- begin
74
- @spec_name = spec_name
75
- spec_types, @versioning, @spec_version = load_chain_spec_types(spec_name)
76
- @types = default_types.merge(spec_types)
77
- rescue => ex
78
- puts "There is no types json file named #{spec_name}"
79
- @types = default_types
80
- end
81
- else
82
- @spec_name = "default"
83
- @types = default_types
84
- end
85
-
86
- self.custom_types = custom_types
87
- true
88
- end
89
-
90
- def get(type_name)
91
- raise "Types not loaded" if @types.nil?
92
-
93
- all_types = {}.merge(@types)
94
-
95
- if @spec_version && @versioning
96
- @versioning.each do |item|
97
- if @spec_version >= item["runtime_range"][0] &&
98
- ( item["runtime_range"][1].nil? || @spec_version <= item["runtime_range"][1] )
99
- all_types.merge!(item["types"])
100
- end
101
- end
102
- end
103
-
104
- all_types.merge!(@custom_types) if @custom_types
105
-
106
- type = type_traverse(type_name, all_types)
107
-
108
- Scale::Types.constantize(type)
109
- end
110
-
111
- def custom_types=(custom_types)
112
- @custom_types = custom_types.stringify_keys if (not custom_types.nil?) && custom_types.class.name == "Hash"
113
- end
114
-
115
- private
116
-
117
- def load_chain_spec_types(spec_name)
118
- file = File.join File.expand_path("../..", __FILE__), "lib", "type_registry", "#{spec_name}.json"
119
- json_string = File.open(file).read
120
- json = JSON.parse(json_string)
121
-
122
- runtime_id = json["runtime_id"]
123
-
124
- [json["types"], json["versioning"], runtime_id]
125
- end
126
-
127
- def type_traverse(type, types)
128
- type = rename(type) if type.class == ::String
129
- if types.has_key?(type) && types[type] != type
130
- type_traverse(types[type], types)
131
- else
132
- type
133
- end
134
- end
135
- end
136
-
137
- # TODO: == implement
138
-
139
- class Bytes
140
- attr_reader :data, :bytes
141
- attr_reader :offset
142
-
143
- def initialize(data)
144
- if (data.class == Array) && data.is_byte_array?
145
- @bytes = data
146
- elsif (data.class == String) && data.start_with?("0x") && (data.length % 2 == 0)
147
- arr = data[2..].scan(/../).map(&:hex)
148
- @bytes = arr
149
- else
150
- raise "Provided data is not valid"
151
- end
152
-
153
- @data = data
154
- @offset = 0
155
- end
156
-
157
- def reset_offset
158
- @offset = 0
159
- end
160
-
161
- def get_next_bytes(length)
162
- result = @bytes[@offset...@offset + length]
163
- if result.length < length
164
- str = @data[(2 + @offset * 2)..]
165
- str = str.length > 40 ? (str[0...40]).to_s + "..." : str
166
- raise "No enough data: #{str}, expect length: #{length}, but #{result.length}"
167
- end
168
- @offset += length
169
- result
170
- rescue RangeError => ex
171
- puts "length: #{length}"
172
- puts ex.message
173
- puts ex.backtrace
174
- end
175
-
176
- def get_remaining_bytes
177
- @bytes[offset..]
178
- end
179
-
180
- def to_hex_string
181
- @bytes.bytes_to_hex
182
- end
183
-
184
- def to_bin_string
185
- @bytes.bytes_to_bin
186
- end
187
-
188
- def to_ascii
189
- @bytes[0...offset].pack("C*") + "<================================>" + @bytes[offset..].pack("C*")
190
- end
191
-
192
- def ==(other)
193
- bytes == other.bytes && offset == other.offset
194
- end
195
-
196
- def to_s
197
- green(@bytes[0...offset].bytes_to_hex) + yellow(@bytes[offset..].bytes_to_hex[2..])
198
- end
199
- end
200
-
201
- class TypesLoader
202
- def self.load(filename)
203
- path = File.join File.dirname(__FILE__), "types", filename
204
- content = File.open(path).read
205
- result = JSON.parse content
206
-
207
- types = result["default"]
208
- types.each do |name, body|
209
- if body.class == String
210
- target_type = "Scale::Types::#{body}"
211
- klass = Class.new(target_type.constantize2) do
212
- end
213
- elsif body.class == Hash
214
- if body["type"] == "struct"
215
- struct_params = {}
216
- body["type_mapping"].each do |mapping|
217
- struct_params[mapping[0].to_sym] = mapping[1]
218
- end
219
- klass = Class.new do
220
- end
221
- klass.send(:include, Scale::Types::Struct)
222
- klass.send(:items, struct_params)
223
- Scale::Types.const_set name, klass
224
- elsif body["type"] = "enum"
225
- klass = Class.new do
226
- end
227
- klass.send(:include, Scale::Types::Enum)
228
- if body["type_mapping"]
229
- struct_params = {}
230
- body["type_mapping"].each do |mapping|
231
- struct_params[mapping[0].to_sym] = mapping[1]
232
- end
233
- klass.send(:items, struct_params)
234
- else
235
- klass.send(:values, body["value_list"])
236
- end
237
- Scale::Types.const_set name, klass
238
- end
239
- end
240
- end
241
- end
242
- end
39
+ class ScaleError < StandardError; end
40
+ class TypeBuildError < ScaleError; end
41
+ class BadDataError < ScaleError; end
42
+ class TypeRegistryNotLoadYet < ScaleError; end
43
+ class StorageInputTypeError < ScaleError; end
243
44
 
244
45
  module Types
245
46
  class << self
246
- attr_accessor :debug
247
- end
248
-
249
- def self.list
250
- TypeRegistry.instance.types
251
- end
252
-
253
- def self.get(type_name)
254
- type = TypeRegistry.instance.get(type_name)
255
- raise "Type '#{type_name}' not exist" if type.nil?
256
- type
257
- end
258
-
259
- def self.constantize(type)
260
- if type.class == ::String
261
- type_of(type.strip)
262
- else
263
- if type["type"] == "enum" && type.has_key?("type_mapping")
264
- type_of("Enum", type["type_mapping"].to_h)
265
- elsif type["type"] == "enum" && type.has_key?("value_list")
266
- type_of("Enum", type["value_list"])
267
- elsif type["type"] == "struct"
268
- type_of("Struct", type["type_mapping"].to_h)
269
- elsif type["type"] == "set"
270
- type_of("Set", type["value_list"])
271
- end
272
- end
47
+ attr_accessor :debug, :logger
273
48
  end
274
49
 
275
- def self.type_of(type_string, values = nil)
276
- if type_string.end_with?(">")
277
- type_strs = type_string.scan(/^([^<]*)<(.+)>$/).first
278
- type_str = type_strs.first
279
- inner_type_str = type_strs.last
280
-
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
306
- end
307
- else
308
- raise "#{type_str} not support inner type: #{type_string}"
309
- end
310
- elsif type_string.start_with?("(") && type_string.end_with?(")") # tuple
311
- # TODO: add nested tuple support
312
- types_with_inner_type = type_string[1...-1].scan(/([A-Za-z]+<[^>]*>)/).first
313
-
314
- types_with_inner_type&.each do |type_str|
315
- new_type_str = type_str.tr(",", ";")
316
- type_string = type_string.gsub(type_str, new_type_str)
317
- end
318
-
319
- type_strs = type_string[1...-1].split(",").map do |type_str|
320
- type_str.strip.tr(";", ",")
321
- end
322
-
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
333
- end
334
- else
335
- if type_string == "Enum"
336
- # TODO: combine values to items
337
- klass = Class.new do
338
- include Scale::Types::Enum
339
- if values.class == ::Hash
340
- items values
341
- else
342
- values(*values)
343
- end
344
- end
345
- name = values.class == ::Hash ? values.values.map(&:camelize2).join("_") : values.map(&:camelize2).join("_")
346
- name = "Enum_Of_#{name}_#{klass.object_id}"
347
- Scale::Types.const_set fix(name), klass
348
- elsif type_string == "Struct"
349
- klass = Class.new do
350
- include Scale::Types::Struct
351
- items values
352
- end
353
- name = "Struct_Of_#{values.values.map(&:camelize2).join("_")}_#{klass.object_id}"
354
- Scale::Types.const_set fix(name), klass
355
- elsif type_string == "Set"
356
- klass = Class.new do
357
- include Scale::Types::Set
358
- items values, 1
359
- end
360
- name = "Set_Of_#{values.keys.map(&:camelize2).join("_")}_#{klass.object_id}"
361
- Scale::Types.const_set fix(name), klass
362
- else
363
- type_name = (type_string.start_with?("Scale::Types::") ? type_string : "Scale::Types::#{type_string}")
364
- begin
365
- type_name.constantize2
366
- rescue NameError => e
367
- puts "#{type_string} is not defined"
368
- end
50
+ def self.check_types
51
+ TypeRegistry.instance.all_types.keys.each do |key|
52
+ begin
53
+ type = self.get(key)
54
+ rescue => ex
55
+ puts "[[ERROR]] #{key}: #{ex}"
369
56
  end
370
57
  end
58
+ true
371
59
  end
372
- end
373
-
374
- end
375
-
376
- # def fix(name)
377
- # name
378
- # .gsub("<", "˂").gsub(">", "˃")
379
- # .gsub("(", "⁽").gsub(")", "⁾")
380
- # .gsub(" ", "").gsub(",", "‚")
381
- # .gsub(":", "։")
382
- # end
383
-
384
- def fix(name)
385
- name
386
- .gsub("<", "").gsub(">", "")
387
- .gsub("(", "").gsub(")", "")
388
- .gsub(" ", "").gsub(",", "")
389
- .gsub(":", "")
390
- end
391
60
 
392
- def rename(type)
393
- type = type.gsub("T::", "")
394
- .gsub("<T>", "")
395
- .gsub("<T as Trait>::", "")
396
- .delete("\n")
397
- .gsub("EventRecord<Event, Hash>", "EventRecord")
398
- .gsub(/(u)(\d+)/, 'U\2')
399
- return "Bool" if type == "bool"
400
- return "Null" if type == "()"
401
- return "String" if type == "Vec<u8>"
402
- return "Compact" if type == "Compact<u32>" || type == "Compact<U32>"
403
- return "Address" if type == "<Lookup as StaticLookup>::Source"
404
- return "Vec<Address>" if type == "Vec<<Lookup as StaticLookup>::Source>"
405
- return "Compact" if type == "<Balance as HasCompact>::Type"
406
- return "Compact" if type == "<BlockNumber as HasCompact>::Type"
407
- return "Compact" if type == "Compact<Balance>"
408
- return "Compact" if type == "Compact<BlockNumber>"
409
- return "CompactMoment" if type == "<Moment as HasCompact>::Type"
410
- return "CompactMoment" if type == "Compact<Moment>"
411
- return "InherentOfflineReport" if type == "<InherentOfflineReport as InherentOfflineReport>::Inherent"
412
- return "AccountData" if type == "AccountData<Balance>"
413
-
414
- if type =~ /\[U\d+; \d+\]/
415
- byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first.to_i
416
- return "VecU8Length#{byte_length}"
417
61
  end
418
-
419
- type
420
62
  end
421
63
 
422
64
  def green(text)
@@ -427,6 +69,24 @@ def yellow(text)
427
69
  "\033[33m#{text}\033[0m"
428
70
  end
429
71
 
72
+ class String
73
+ def upcase_first
74
+ self.sub(/\S/, &:upcase)
75
+ end
76
+
77
+ def camelize2
78
+ self.split('_').collect(&:upcase_first).join
79
+ end
80
+
81
+ def underscore2
82
+ self.gsub(/::/, '/').
83
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
84
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
85
+ tr("-", "_").
86
+ downcase
87
+ end
88
+ end
89
+
430
90
  # https://www.ruby-forum.com/t/question-about-hex-signed-int/125510/4
431
91
  # machine bit length:
432
92
  # machine_byte_length = ['foo'].pack('p').size
@@ -466,3 +126,4 @@ class ::Hash
466
126
  end
467
127
 
468
128
  Scale::Types.debug = false
129
+ Scale::Types.logger = Logger.new(STDOUT)