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.
- checksums.yaml +4 -4
- data/.devcontainer/devcontainer.json +21 -0
- data/Dockerfile +16 -0
- data/Gemfile +4 -4
- data/README.md +19 -6
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/examples/http_client_1.rb +0 -2
- data/examples/http_client_2.rb +0 -2
- data/examples/ws_client_1.rb +0 -2
- data/examples/ws_client_3.rb +1 -3
- data/examples/ws_client_4.rb +0 -2
- data/exe/metadata +9 -11
- data/lib/address.rb +1 -1
- data/lib/custom_assign.rb +92 -0
- data/lib/scale_rb/call_helper.rb +42 -0
- data/lib/{client → scale_rb/client}/client_ext.rb +12 -13
- data/lib/{client → scale_rb/client}/http_client.rb +3 -5
- data/lib/{client → scale_rb/client}/ws_client.rb +13 -20
- data/lib/scale_rb/codec.rb +25 -0
- data/lib/scale_rb/codec_utils.rb +128 -0
- data/lib/scale_rb/decode.rb +164 -0
- data/lib/scale_rb/encode.rb +150 -0
- data/lib/{hasher.rb → scale_rb/hasher.rb} +10 -8
- data/lib/scale_rb/metadata/metadata.rb +114 -0
- data/lib/{metadata → scale_rb/metadata}/metadata_v10.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v11.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v12.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v13.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v14.rb +18 -18
- data/lib/{metadata → scale_rb/metadata}/metadata_v9.rb +0 -17
- data/lib/scale_rb/metadata/registry.rb +263 -0
- data/lib/scale_rb/metadata/type_exp.rb +286 -0
- data/lib/scale_rb/portable_registry.rb +133 -0
- data/lib/{storage_helper.rb → scale_rb/storage_helper.rb} +16 -4
- data/lib/scale_rb/types.rb +233 -0
- data/lib/scale_rb/utils.rb +125 -0
- data/lib/scale_rb/version.rb +1 -1
- data/lib/scale_rb.rb +22 -30
- data/lib/type_enforcer.rb +170 -0
- data/scale_rb.gemspec +5 -0
- metadata +71 -19
- data/lib/codec.rb +0 -450
- data/lib/metadata/metadata.rb +0 -137
- data/lib/monkey_patching.rb +0 -115
- data/lib/portable_codec.rb +0 -285
- data/lib/registry.rb +0 -13
data/lib/portable_codec.rb
DELETED
@@ -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
|