scale_rb 0.1.13 → 0.1.14

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: e442bed63503c0e8c7210753df2fa8a293a094c4df6e095f649997923a4d65c6
4
- data.tar.gz: 97c1bc3b28346baf2f28a93a5a302240d327b663fc7acad7f0bdbd5c558a8e2e
3
+ metadata.gz: 82a0911194368a4fcefec7a414694346f087c0ded749d3865f6732f27c8afef0
4
+ data.tar.gz: 14b34a748f835c527726ebd42440cced5ed8b5c0d954cb15c41e288ce3e5aff6
5
5
  SHA512:
6
- metadata.gz: b233f131d753ca6bb5f632523da0d09be97d2f721a9933c63c6def842ea55de30fd6a7f46081c0113b114b48ce15ed1193b5b834e382379e2406a8eb3416c012
7
- data.tar.gz: 7f97fd3d9927fd3873717226e1294209af285062314850af0d9000e46cdb657b033c3536d19da6cd1bbc6baaeed6f39d729ea7ec3bfcd0c381e75bcfcf1afd5b
6
+ metadata.gz: 805efca604cc93794b5c1d4ee3dd1785d74d6a049b55f0ecc0503c85869c2759a37380b6735b8ecf874b6b33b31492f7b203870b7b414758740545821f98db19
7
+ data.tar.gz: d5f577ec96adf7a51ef7044b0d5f8bc874e3a12daf66e3cc743677a6a095ddda909267b941dd15a06646dc941caeabe810fd960140c1c94261d173796ee40b9d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- scale_rb (0.1.13)
4
+ scale_rb (0.1.14)
5
5
  base58
6
6
  blake2b_rs (~> 0.1.4)
7
7
  xxhash
@@ -14,7 +14,7 @@ GEM
14
14
  ffi (~> 1.0)
15
15
  thermite (~> 0)
16
16
  diff-lcs (1.5.0)
17
- ffi (1.15.5)
17
+ ffi (1.16.3)
18
18
  minitar (0.9)
19
19
  rake (12.3.3)
20
20
  rspec (3.11.0)
data/lib/address.rb CHANGED
@@ -14,7 +14,7 @@ class Address
14
14
  # Darwinia Live
15
15
  18,
16
16
  # Dothereum (SS58, AccountId)
17
- 20, 21,
17
+ 20, 21,
18
18
  # Generic Substrate wildcard (SS58, AccountId)
19
19
  42, 43,
20
20
 
@@ -30,54 +30,62 @@ class Address
30
30
  ]
31
31
 
32
32
  class << self
33
-
34
33
  def array_to_hex_string(arr)
35
34
  body = arr.map { |i| i.to_s(16).rjust(2, '0') }.join
36
35
  "0x#{body}"
37
36
  end
38
37
 
39
- def decode(address, addr_type = 42, ignore_checksum = true)
38
+ def decode(address, addr_type = 42, _ignore_checksum = true)
40
39
  decoded = Base58.base58_to_binary(address, :bitcoin)
41
40
  is_pubkey = decoded.size == 35
42
41
 
43
- size = decoded.size - ( is_pubkey ? 2 : 1 )
42
+ size = decoded.size - (is_pubkey ? 2 : 1)
43
+
44
+ prefix = decoded[0, 1].unpack1('C*')
44
45
 
45
- prefix = decoded[0, 1].unpack("C*").first
46
+ raise 'Invalid address type' unless TYPES.include?(addr_type)
46
47
 
47
- raise "Invalid address type" unless TYPES.include?(addr_type)
48
-
49
48
  hash_bytes = make_hash(decoded[0, size])
50
- if is_pubkey
51
- is_valid_checksum = decoded[-2].unpack("C*").first == hash_bytes[0] && decoded[-1].unpack("C*").first == hash_bytes[1]
52
- else
53
- is_valid_checksum = decoded[-1].unpack("C*").first == hash_bytes[0]
54
- end
49
+ is_valid_checksum =
50
+ if is_pubkey
51
+ decoded[-2].unpack1('C*') == hash_bytes[0] && decoded[-1].unpack1('C*') == hash_bytes[1]
52
+ else
53
+ decoded[-1].unpack1('C*') == hash_bytes[0]
54
+ end
55
55
 
56
56
  # raise "Invalid decoded address checksum" unless is_valid_checksum && ignore_checksum
57
57
 
58
- decoded[1...size].unpack("H*").first
58
+ decoded[1...size].unpack1('H*')
59
59
  end
60
60
 
61
-
62
61
  def encode(pubkey, addr_type = 42)
63
62
  pubkey = pubkey[2..-1] if pubkey =~ /^0x/i
64
- key = [pubkey].pack("H*")
65
-
66
- u8_array = key.bytes
67
-
68
- u8_array.unshift(addr_type)
69
-
70
- bytes = make_hash(u8_array.pack("C*"))
71
-
72
- checksum = bytes[0, key.size == 32 ? 2 : 1]
73
-
74
- u8_array.push(*checksum)
75
-
76
- u8_array = u8_array.map { |i| if i.is_a?(String) then i.to_i(16) else i end }
77
- # u8_array = [42, 202, 122, 179, 154, 86, 153, 242, 157, 207, 38, 115, 170, 163, 73, 75, 72, 81, 26, 186, 224, 220, 60, 101, 15, 243, 152, 246, 95, 229, 225, 18, 56, 0x7e]
78
- input = u8_array.pack("C*")
79
-
80
- Base58.binary_to_base58(input, :bitcoin)
63
+ key = [pubkey].pack('H*')
64
+
65
+ pubkey_bytes = key.bytes
66
+
67
+ checksum_length = case pubkey_bytes.length
68
+ when 32, 33
69
+ 2
70
+ when 1, 2, 4, 8
71
+ 1
72
+ else
73
+ raise 'Invalid pubkey length'
74
+ end
75
+
76
+ ss58_format_bytes = if addr_type < 64
77
+ [addr_type].pack('C*')
78
+ else
79
+ [
80
+ ((ss58_format & 0b0000_0000_1111_1100) >> 2) | 0b0100_0000,
81
+ (ss58_format >> 8) | ((ss58_format & 0b0000_0000_0000_0011) << 6)
82
+ ].pack('C*')
83
+ end
84
+
85
+ input_bytes = ss58_format_bytes.bytes + pubkey_bytes
86
+ checksum = Blake2b.hex(SS58_PREFIX.bytes + input_bytes, 64).to_bytes
87
+
88
+ Base58.binary_to_base58((input_bytes + checksum[0...checksum_length]).pack('C*'), :bitcoin)
81
89
  end
82
90
 
83
91
  def make_hash(body)
@@ -87,11 +95,11 @@ class Address
87
95
  def is_ss58_address?(address)
88
96
  begin
89
97
  decode(address)
90
- rescue
98
+ rescue StandardError
91
99
  return false
92
100
  end
93
- return true
101
+ true
94
102
  end
95
-
96
103
  end
97
- end
104
+ end
105
+
@@ -3,6 +3,7 @@
3
3
  require 'uri'
4
4
  require 'net/http'
5
5
  require 'json'
6
+ require_relative './http_client_metadata'
6
7
 
7
8
  # TODO: method_name = cmd.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
8
9
  module ScaleRb
@@ -129,17 +130,30 @@ module ScaleRb
129
130
  #
130
131
  # TODO: part of the key is provided, but not all
131
132
  def get_storage(url, pallet_name, item_name, key, value, registry, at = nil)
132
- # map, but no key's value provided. get all storages under the partial storage key
133
- if key && (key[:value].nil? || key[:value].empty?)
134
- partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name).to_hex
135
- get_storages_by_partial_key(
136
- url,
137
- partial_storage_key,
138
- value[:type],
139
- value[:modifier] == 'Default' ? value[:fallback] : nil,
140
- registry,
141
- at
142
- )
133
+ if key
134
+ if key[:value].nil? || key[:value].empty?
135
+ # map, but no key's value provided. get all storages under the partial storage key
136
+ partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name).to_hex
137
+ get_storages_by_partial_key(
138
+ url,
139
+ partial_storage_key,
140
+ value[:type],
141
+ value[:modifier] == 'Default' ? value[:fallback] : nil,
142
+ registry,
143
+ at
144
+ )
145
+ elsif key[:value].length != key[:hashers].length
146
+ # map with multi part, but only provide part value
147
+ partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
148
+ get_storages_by_partial_key(
149
+ url,
150
+ partial_storage_key,
151
+ value[:type],
152
+ value[:modifier] == 'Default' ? value[:fallback] : nil,
153
+ registry,
154
+ at
155
+ )
156
+ end
143
157
  else
144
158
  storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry).to_hex
145
159
  data = state_getStorage(url, storage_key, at)
@@ -0,0 +1,76 @@
1
+ require 'json'
2
+ require 'fileutils'
3
+
4
+ module ScaleRb
5
+ module HttpClient
6
+ class << self
7
+ # cached version of get_metadata
8
+ # get metadata from cache first
9
+ def get_metadata_cached(url, at: nil, dir: File.join(Dir.pwd, 'metadata'))
10
+ # if at
11
+ # require_block_hash_correct(url, at)
12
+ # else
13
+ # at = ScaleRb::HttpClient.chain_getFinalizedHead(url)
14
+ # end
15
+ at = ScaleRb::HttpClient.chain_getFinalizedHead(url) if at.nil?
16
+ spec_name, spec_version = get_spec(url, at)
17
+
18
+ # get metadata from cache first
19
+ metadata = metadata_cached(
20
+ spec_name: spec_name,
21
+ spec_version: spec_version,
22
+ dir: dir
23
+ )
24
+ return metadata if metadata
25
+
26
+ # get metadata from rpc
27
+ metadata = ScaleRb::HttpClient.get_metadata(url, at)
28
+
29
+ # cache it
30
+ puts "caching metadata `#{spec_name}_#{spec_version}.json`"
31
+ save_metadata_to_file(
32
+ spec_name: spec_name,
33
+ spec_version: spec_version,
34
+ metadata: metadata,
35
+ dir: dir
36
+ )
37
+
38
+ metadata
39
+ end
40
+
41
+ private
42
+
43
+ def get_spec(url, at)
44
+ runtime_version = ScaleRb::HttpClient.state_getRuntimeVersion(url, at)
45
+ spec_name = runtime_version['specName']
46
+ spec_version = runtime_version['specVersion']
47
+ [spec_name, spec_version]
48
+ end
49
+
50
+ def metadata_cached(spec_name:, spec_version:, dir:)
51
+ raise 'spec_version is required' unless spec_version
52
+ raise 'spec_name is required' unless spec_name
53
+
54
+ file_path = File.join(dir, "#{spec_name}_#{spec_version}.json")
55
+ return unless File.exist?(file_path)
56
+
57
+ puts "found metadata `#{spec_name}_#{spec_version}.json` in cache"
58
+ JSON.parse(File.read(file_path))
59
+ end
60
+
61
+ def save_metadata_to_file(spec_name:, spec_version:, metadata:, dir:)
62
+ FileUtils.mkdir_p(dir)
63
+
64
+ File.open(File.join(dir, "#{spec_name}_#{spec_version}.json"), 'w') do |f|
65
+ f.write(JSON.pretty_generate(metadata))
66
+ end
67
+ end
68
+
69
+ def require_block_hash_correct(url, block_hash)
70
+ return unless ScaleRb::HttpClient.chain_getHeader(url, block_hash).nil?
71
+
72
+ raise 'Unable to retrieve header and parent from supplied hash'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module ScaleRb
2
- VERSION = '0.1.13'
2
+ VERSION = '0.1.14'
3
3
  end
@@ -12,26 +12,26 @@ module StorageHelper
12
12
 
13
13
  if key && registry
14
14
 
15
- key_types, key_values =
15
+ key_types, key_values, key_hashers =
16
16
  if key[:hashers].length == 1
17
17
  [
18
18
  [key[:type]],
19
- key[:value]
19
+ key[:value],
20
+ key[:hashers]
20
21
  ]
21
22
  else
22
23
  [
23
- registry[key[:type]]._get(:def)._get(:tuple),
24
- key[:value]
24
+ registry[key[:type]]._get(:def)._get(:tuple).first(key[:value].length),
25
+ key[:value],
26
+ key[:hashers].first(key[:value].length)
25
27
  ]
26
28
  end
27
29
 
28
- # debug
29
- # p "encode_storage_key -----------------------"
30
- # p key_types
31
- # p key_values
32
- # p "encode_storage_key -----------------------"
33
- raise "Key's value doesn't match key's type, key's value: #{key_values.inspect}, but key's type: #{key_types.inspect}. Please check your key's value." if key_types.class != key_values.class || key_types.length != key_values.length
34
- storage_key + PortableCodec._encode_types_with_hashers(key_types, key_values, registry, key[:hashers])
30
+ if key_types.class != key_values.class || key_types.length != key_values.length
31
+ raise "Key's value doesn't match key's type, key's value: #{key_values.inspect}, but key's type: #{key_types.inspect}. Please check your key's value."
32
+ end
33
+
34
+ storage_key + PortableCodec._encode_types_with_hashers(key_types, key_values, registry, key_hashers)
35
35
  else
36
36
  storage_key
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scale_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aki Wu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-25 00:00:00.000000000 Z
11
+ date: 2023-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: blake2b_rs
@@ -76,6 +76,7 @@ files:
76
76
  - lib/address.rb
77
77
  - lib/client/abstract_ws_client.rb
78
78
  - lib/client/http_client.rb
79
+ - lib/client/http_client_metadata.rb
79
80
  - lib/client/rpc_request_builder.rb
80
81
  - lib/codec.rb
81
82
  - lib/hasher.rb