scale_rb 0.4.1 → 0.5.0

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +21 -0
  3. data/Dockerfile +16 -0
  4. data/Gemfile +4 -4
  5. data/README.md +19 -6
  6. data/bin/console +0 -0
  7. data/bin/setup +0 -0
  8. data/examples/http_client_1.rb +0 -2
  9. data/examples/http_client_2.rb +0 -2
  10. data/examples/ws_client_1.rb +0 -2
  11. data/examples/ws_client_3.rb +1 -3
  12. data/examples/ws_client_4.rb +0 -2
  13. data/exe/metadata +9 -11
  14. data/lib/address.rb +1 -1
  15. data/lib/custom_assign.rb +92 -0
  16. data/lib/scale_rb/call_helper.rb +42 -0
  17. data/lib/{client → scale_rb/client}/client_ext.rb +12 -13
  18. data/lib/{client → scale_rb/client}/http_client.rb +3 -5
  19. data/lib/{client → scale_rb/client}/ws_client.rb +13 -20
  20. data/lib/scale_rb/codec.rb +25 -0
  21. data/lib/scale_rb/codec_utils.rb +128 -0
  22. data/lib/scale_rb/decode.rb +164 -0
  23. data/lib/scale_rb/encode.rb +150 -0
  24. data/lib/{hasher.rb → scale_rb/hasher.rb} +10 -8
  25. data/lib/scale_rb/metadata/metadata.rb +114 -0
  26. data/lib/{metadata → scale_rb/metadata}/metadata_v10.rb +0 -17
  27. data/lib/{metadata → scale_rb/metadata}/metadata_v11.rb +0 -17
  28. data/lib/{metadata → scale_rb/metadata}/metadata_v12.rb +0 -17
  29. data/lib/{metadata → scale_rb/metadata}/metadata_v13.rb +0 -17
  30. data/lib/{metadata → scale_rb/metadata}/metadata_v14.rb +18 -18
  31. data/lib/{metadata → scale_rb/metadata}/metadata_v9.rb +0 -17
  32. data/lib/scale_rb/metadata/registry.rb +263 -0
  33. data/lib/scale_rb/metadata/type_exp.rb +286 -0
  34. data/lib/scale_rb/portable_registry.rb +133 -0
  35. data/lib/{storage_helper.rb → scale_rb/storage_helper.rb} +16 -4
  36. data/lib/scale_rb/types.rb +233 -0
  37. data/lib/scale_rb/utils.rb +125 -0
  38. data/lib/scale_rb/version.rb +1 -1
  39. data/lib/scale_rb.rb +22 -30
  40. data/lib/type_enforcer.rb +170 -0
  41. data/scale_rb.gemspec +5 -0
  42. metadata +71 -19
  43. data/lib/codec.rb +0 -450
  44. data/lib/metadata/metadata.rb +0 -137
  45. data/lib/monkey_patching.rb +0 -115
  46. data/lib/portable_codec.rb +0 -285
  47. data/lib/registry.rb +0 -13
@@ -1,285 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ScaleRb
4
- module PortableCodec
5
- class Error < StandardError; end
6
- class TypeNotFound < Error; end
7
- class TypeNotImplemented < Error; end
8
- class CompositeInvalidValue < Error; end
9
- class ArrayLengthNotEqual < Error; end
10
- class VariantItemNotFound < Error; end
11
- class VariantIndexOutOfRange < Error; end
12
- class VariantInvalidValue < Error; end
13
-
14
- class << self
15
- def u256(value)
16
- bytes = ScaleRb.encode('u256', value)
17
- bytes.each_slice(8).map do |slice|
18
- ScaleRb.decode('u64', slice).first
19
- end
20
- end
21
- end
22
-
23
- class << self
24
- # registry:
25
- # {
26
- # 0 => {
27
- # path: [...],
28
- # params: [...],
29
- # def: {
30
- # primitive: 'u8' | array: {} | ...
31
- # }
32
- # },
33
- # 1 => {
34
- # ...
35
- # }
36
- # }
37
- def decode(id, bytes, registry)
38
- type = registry[id]
39
- raise TypeNotFound, "id: #{id}" if type.nil?
40
-
41
- _path = type._get(:path)
42
- _params = type._get(:params)
43
- type_def = type._get(:def)
44
-
45
- return decode_primitive(type_def, bytes) if type_def._key?(:primitive)
46
- return decode_compact(bytes) if type_def._key?(:compact)
47
- return decode_array(type_def._get(:array), bytes, registry) if type_def._key?(:array)
48
- return decode_sequence(type_def._get(:sequence), bytes, registry) if type_def._key?(:sequence)
49
- return decode_tuple(type_def._get(:tuple), bytes, registry) if type_def._key?(:tuple)
50
- return decode_composite(type_def._get(:composite), bytes, registry) if type_def._key?(:composite)
51
- return decode_variant(type_def._get(:variant), bytes, registry) if type_def._key?(:variant)
52
-
53
- raise TypeNotImplemented, "id: #{id}"
54
- end
55
-
56
- # Uint, Str, Bool
57
- # Int, Bytes ?
58
- def decode_primitive(type_def, bytes)
59
- primitive = type_def._get(:primitive)
60
- return ScaleRb.decode_uint(primitive, bytes) if ScaleRb.uint?(primitive)
61
- return ScaleRb.decode_string(bytes) if ScaleRb.string?(primitive)
62
-
63
- ScaleRb.decode_boolean(bytes) if ScaleRb.boolean?(primitive)
64
- # return ScaleRb.decode_int(primitive, bytes) if int?(primitive)
65
- # return ScaleRb.decode_bytes(bytes) if bytes?(primitive)
66
- end
67
-
68
- def decode_compact(bytes)
69
- ScaleRb.decode_compact(bytes)
70
- end
71
-
72
- def decode_array(array_type, bytes, registry)
73
- len = array_type._get(:len)
74
- inner_type_id = array_type._get(:type)
75
-
76
- # check if the type of inner_type_id is a u8
77
- if _u8?(inner_type_id, registry)
78
- [
79
- bytes[0...len]._to_hex,
80
- bytes[len..]
81
- ]
82
- else
83
- _decode_types([inner_type_id] * len, bytes, registry)
84
- end
85
- end
86
-
87
- def _u8?(type_id, registry)
88
- type = registry[type_id]
89
- raise TypeNotFound, "id: #{type_id}" if type.nil?
90
-
91
- type._get(:def)._get(:primitive)&.downcase == 'u8'
92
- end
93
-
94
- def decode_sequence(sequence_type, bytes, registry)
95
- len, remaining_bytes = decode_compact(bytes)
96
- inner_type_id = sequence_type._get(:type)
97
- _decode_types([inner_type_id] * len, remaining_bytes, registry)
98
- end
99
-
100
- def decode_tuple(tuple_type, bytes, registry)
101
- _decode_types(tuple_type, bytes, registry)
102
- end
103
-
104
- # {
105
- # name: value,
106
- # ...
107
- # }
108
- def decode_composite(composite_type, bytes, registry)
109
- fields = composite_type._get(:fields)
110
-
111
- # reduce composite level when composite only has one field without name
112
- if fields.length == 1 && fields.first._get(:name).nil?
113
- decode(fields.first._get(:type), bytes, registry)
114
- else
115
- type_name_list = fields.map { |f| f._get(:name) }
116
- type_id_list = fields.map { |f| f._get(:type) }
117
-
118
- type_value_list, remaining_bytes = _decode_types(type_id_list, bytes, registry)
119
- [
120
- if type_name_list.all?(&:nil?)
121
- type_value_list
122
- else
123
- [type_name_list.map(&:to_sym), type_value_list].transpose.to_h
124
- end,
125
- remaining_bytes
126
- ]
127
- end
128
- end
129
-
130
- def decode_variant(variant_type, bytes, registry)
131
- variants = variant_type._get(:variants)
132
-
133
- index = bytes[0].to_i # TODO: check
134
- item = variants.find { |v| v._get(:index) == index } # item is an composite
135
-
136
- raise VariantIndexOutOfRange, "type: #{variant_type}, index: #{index}, bytes: #{bytes}" if item.nil?
137
-
138
- item_name = item._get(:name)
139
- item_fields = item._get(:fields)
140
- if item_fields.empty?
141
- [item_name, bytes[1..]]
142
- else
143
- item_value, remaining_bytes = decode_composite(item, bytes[1..], registry)
144
- [{ item_name.to_sym => item_value }, remaining_bytes]
145
- end
146
- end
147
-
148
- def _decode_types(ids, bytes, registry = {})
149
- ScaleRb._decode_each(ids, bytes) do |id, remaining_bytes|
150
- decode(id, remaining_bytes, registry)
151
- end
152
- end
153
-
154
- def encode_with_hasher(value, type_id, registry, hasher)
155
- value_bytes = encode(type_id, value, registry)
156
- Hasher.apply_hasher(hasher, value_bytes)
157
- end
158
-
159
- def encode(id, value, registry)
160
- type = registry[id]
161
- raise TypeNotFound, "id: #{id}" if type.nil?
162
-
163
- type_def = type._get(:def)
164
- # debug
165
- # p type_def
166
- # p value
167
-
168
- return encode_primitive(type_def, value) if type_def._key?(:primitive)
169
- return encode_compact(value) if type_def._key?(:compact)
170
- return encode_array(type_def._get(:array), value, registry) if type_def._key?(:array)
171
- return encode_sequence(type_def._get(:sequence), value, registry) if type_def._key?(:sequence)
172
- return encode_tuple(type_def._get(:tuple), value, registry) if type_def._key?(:tuple)
173
- return encode_composite(type_def._get(:composite), value, registry) if type_def._key?(:composite)
174
- return encode_variant(type_def._get(:variant), value, registry) if type_def._key?(:variant)
175
-
176
- raise TypeNotImplemented, "id: #{id}"
177
- end
178
-
179
- def encode_primitive(type_def, value)
180
- primitive = type_def._get(:primitive)
181
- return ScaleRb.encode_uint(primitive, value) if ScaleRb.uint?(primitive)
182
- return ScaleRb.encode_string(value) if ScaleRb.string?(primitive)
183
-
184
- ScaleRb.encode_boolean(value) if ScaleRb.boolean?(primitive)
185
- end
186
-
187
- def encode_compact(value)
188
- ScaleRb.encode_compact(value)
189
- end
190
-
191
- def encode_array(array_type, value, registry)
192
- length = array_type._get(:len)
193
- inner_type_id = array_type._get(:type)
194
- raise ArrayLengthNotEqual, "type: #{array_type}, value: #{value.inspect}" if length != value.length
195
-
196
- _encode_types([inner_type_id] * length, value, registry)
197
- end
198
-
199
- def encode_sequence(sequence_type, value, registry)
200
- inner_type_id = sequence_type._get(:type)
201
- length_bytes = encode_compact(value.length)
202
- length_bytes + _encode_types([inner_type_id] * value.length, value, registry)
203
- end
204
-
205
- # tuple_type: [type_id1, type_id2, ...]
206
- def encode_tuple(tuple_type, value, registry)
207
- _encode_types(tuple_type, value, registry)
208
- end
209
-
210
- # value:
211
- # {
212
- # name1: value1,
213
- # name2: value2,
214
- # ...
215
- # }
216
- # or
217
- # [value1, value2, ...]
218
- def encode_composite(composite_type, value, registry)
219
- fields = composite_type._get(:fields)
220
- # reduce composite level when composite only has one field without name
221
- if fields.length == 1 && fields.first._get(:name).nil?
222
- # debug
223
- # p fields.first._get(:type)
224
- # p value
225
- encode(fields.first._get(:type), value, registry)
226
- else
227
- values =
228
- if value.instance_of?(Hash)
229
- value.values
230
- elsif value.instance_of?(Array)
231
- value
232
- else
233
- raise CompositeInvalidValue, "value: #{value}, only hash and array"
234
- end
235
-
236
- type_id_list = fields.map { |f| f._get(:type) }
237
- _encode_types(type_id_list, values, registry)
238
- end
239
- end
240
-
241
- # value:
242
- # {
243
- # name: v(Hash)
244
- # }
245
- # or
246
- # the_value(String)
247
- def encode_variant(variant_type, value, registry)
248
- variants = variant_type._get(:variants)
249
-
250
- name, v = # v: item inner value
251
- if value.instance_of?(Hash)
252
- [value.keys.first.to_s, value.values.first]
253
- elsif value.instance_of?(String)
254
- [value, {}]
255
- else
256
- raise VariantInvalidValue, "type: #{variant_type}, value: #{value}"
257
- end
258
-
259
- item = variants.find { |var| var._get(:name) == name }
260
- raise VariantItemNotFound, "type: #{variant_type}, name: #{name}" if item.nil?
261
-
262
- # if the variant item has more than one field, the value must be a hash with the same length.
263
- # if the variant item has only one field, that means the field is a type id point to a composite. TODO: check the type's fields length
264
- if item._get(:fields).length > 1 && item._get(:fields).length != v.length
265
- raise VariantFieldsLengthNotMatch,
266
- "type: #{variant_type}, \nvalue: #{v}"
267
- end
268
-
269
- ScaleRb.encode_uint('u8', item._get(:index)) + encode_composite(item, v, registry)
270
- end
271
-
272
- def _encode_types(ids, values, registry)
273
- ScaleRb._encode_each(ids, values) do |id, value|
274
- encode(id, value, registry)
275
- end
276
- end
277
-
278
- def _encode_types_with_hashers(ids, values, registry, hashers)
279
- ScaleRb._encode_each_with_hashers(ids, values, hashers) do |id, value|
280
- encode(id, value, registry)
281
- end
282
- end
283
- end
284
- end
285
- end
data/lib/registry.rb DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ScaleRb
4
- # A `registry` is a ruby Hash object, key is the type name, value is the type definition or mapped type name.
5
- # A `config` contains the complete versioned type definition for a network.
6
- # https://github.com/polkadot-js/api/blob/master/packages/types-known/src/spec/polkadot.ts
7
- def self.build_registry_from_config(config, spec_version)
8
- version = config[:versioned].find do |item|
9
- item[:minmax].include?(spec_version)
10
- end
11
- config[:shared_types].merge(version.nil? ? {} : version[:types])
12
- end
13
- end