tapyrus 0.2.4 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +37 -0
- data/.prettierignore +3 -0
- data/.prettierrc.yaml +3 -0
- data/CODE_OF_CONDUCT.md +7 -7
- data/README.md +14 -17
- data/Rakefile +3 -3
- data/lib/openassets.rb +0 -2
- data/lib/openassets/marker_output.rb +0 -4
- data/lib/openassets/payload.rb +4 -10
- data/lib/schnorr.rb +14 -9
- data/lib/schnorr/sign_to_contract.rb +51 -0
- data/lib/schnorr/signature.rb +3 -6
- data/lib/tapyrus.rb +8 -30
- data/lib/tapyrus/base58.rb +7 -6
- data/lib/tapyrus/bip175.rb +67 -0
- data/lib/tapyrus/block.rb +1 -2
- data/lib/tapyrus/block_header.rb +15 -9
- data/lib/tapyrus/bloom_filter.rb +5 -3
- data/lib/tapyrus/chain_params.rb +1 -4
- data/lib/tapyrus/chainparams/dev.yml +3 -2
- data/lib/tapyrus/chainparams/prod.yml +3 -2
- data/lib/tapyrus/constants.rb +29 -23
- data/lib/tapyrus/errors.rb +1 -3
- data/lib/tapyrus/ext.rb +1 -1
- data/lib/tapyrus/ext/ecdsa.rb +4 -4
- data/lib/tapyrus/ext/json_parser.rb +1 -4
- data/lib/tapyrus/ext_key.rb +44 -32
- data/lib/tapyrus/key.rb +31 -35
- data/lib/tapyrus/key_path.rb +15 -12
- data/lib/tapyrus/logger.rb +20 -16
- data/lib/tapyrus/merkle_tree.rb +19 -20
- data/lib/tapyrus/message.rb +14 -16
- data/lib/tapyrus/message/addr.rb +1 -7
- data/lib/tapyrus/message/base.rb +0 -3
- data/lib/tapyrus/message/block.rb +2 -9
- data/lib/tapyrus/message/block_transaction_request.rb +3 -6
- data/lib/tapyrus/message/block_transactions.rb +2 -6
- data/lib/tapyrus/message/block_txn.rb +0 -4
- data/lib/tapyrus/message/cmpct_block.rb +1 -7
- data/lib/tapyrus/message/error.rb +1 -4
- data/lib/tapyrus/message/fee_filter.rb +1 -4
- data/lib/tapyrus/message/filter_add.rb +0 -4
- data/lib/tapyrus/message/filter_clear.rb +0 -4
- data/lib/tapyrus/message/filter_load.rb +2 -5
- data/lib/tapyrus/message/get_addr.rb +0 -4
- data/lib/tapyrus/message/get_block_txn.rb +0 -4
- data/lib/tapyrus/message/get_blocks.rb +0 -3
- data/lib/tapyrus/message/get_data.rb +1 -4
- data/lib/tapyrus/message/get_headers.rb +1 -3
- data/lib/tapyrus/message/header_and_short_ids.rb +3 -9
- data/lib/tapyrus/message/headers.rb +0 -4
- data/lib/tapyrus/message/headers_parser.rb +3 -8
- data/lib/tapyrus/message/inv.rb +1 -4
- data/lib/tapyrus/message/inventories_parser.rb +2 -7
- data/lib/tapyrus/message/inventory.rb +12 -5
- data/lib/tapyrus/message/mem_pool.rb +0 -4
- data/lib/tapyrus/message/merkle_block.rb +4 -9
- data/lib/tapyrus/message/network_addr.rb +7 -6
- data/lib/tapyrus/message/not_found.rb +0 -3
- data/lib/tapyrus/message/ping.rb +0 -3
- data/lib/tapyrus/message/pong.rb +0 -3
- data/lib/tapyrus/message/prefilled_tx.rb +0 -4
- data/lib/tapyrus/message/reject.rb +0 -3
- data/lib/tapyrus/message/send_cmpct.rb +1 -3
- data/lib/tapyrus/message/send_headers.rb +0 -3
- data/lib/tapyrus/message/tx.rb +0 -4
- data/lib/tapyrus/message/ver_ack.rb +1 -5
- data/lib/tapyrus/message/version.rb +2 -5
- data/lib/tapyrus/mnemonic.rb +17 -15
- data/lib/tapyrus/network.rb +0 -2
- data/lib/tapyrus/network/connection.rb +0 -3
- data/lib/tapyrus/network/message_handler.rb +61 -60
- data/lib/tapyrus/network/peer.rb +13 -12
- data/lib/tapyrus/network/peer_discovery.rb +3 -5
- data/lib/tapyrus/network/pool.rb +12 -12
- data/lib/tapyrus/node.rb +1 -1
- data/lib/tapyrus/node/cli.rb +12 -14
- data/lib/tapyrus/node/configuration.rb +1 -3
- data/lib/tapyrus/node/spv.rb +2 -3
- data/lib/tapyrus/opcodes.rb +9 -7
- data/lib/tapyrus/out_point.rb +5 -5
- data/lib/tapyrus/rpc.rb +1 -0
- data/lib/tapyrus/rpc/http_server.rb +21 -22
- data/lib/tapyrus/rpc/request_handler.rb +42 -44
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +67 -25
- data/lib/tapyrus/script/color.rb +20 -2
- data/lib/tapyrus/script/multisig.rb +13 -12
- data/lib/tapyrus/script/script.rb +104 -67
- data/lib/tapyrus/script/script_error.rb +1 -4
- data/lib/tapyrus/script/script_interpreter.rb +439 -399
- data/lib/tapyrus/script/tx_checker.rb +20 -10
- data/lib/tapyrus/secp256k1.rb +0 -4
- data/lib/tapyrus/secp256k1/native.rb +14 -15
- data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
- data/lib/tapyrus/secp256k1/ruby.rb +10 -12
- data/lib/tapyrus/slip39.rb +20 -5
- data/lib/tapyrus/slip39/share.rb +41 -29
- data/lib/tapyrus/slip39/sss.rb +101 -57
- data/lib/tapyrus/store.rb +1 -3
- data/lib/tapyrus/store/chain_entry.rb +0 -4
- data/lib/tapyrus/store/db.rb +0 -2
- data/lib/tapyrus/store/db/level_db.rb +5 -9
- data/lib/tapyrus/store/spv_chain.rb +11 -17
- data/lib/tapyrus/tx.rb +45 -37
- data/lib/tapyrus/tx_builder.rb +158 -0
- data/lib/tapyrus/tx_in.rb +1 -6
- data/lib/tapyrus/tx_out.rb +2 -7
- data/lib/tapyrus/util.rb +20 -7
- data/lib/tapyrus/validation.rb +12 -11
- data/lib/tapyrus/version.rb +1 -1
- data/lib/tapyrus/wallet/account.rb +22 -18
- data/lib/tapyrus/wallet/base.rb +12 -9
- data/lib/tapyrus/wallet/db.rb +6 -9
- data/lib/tapyrus/wallet/master_key.rb +2 -4
- data/tapyrusrb.gemspec +13 -16
- metadata +22 -31
- data/.travis.yml +0 -12
data/lib/tapyrus/key.rb
CHANGED
@@ -2,10 +2,8 @@
|
|
2
2
|
# https://github.com/lian/bitcoin-ruby/blob/master/COPYING
|
3
3
|
|
4
4
|
module Tapyrus
|
5
|
-
|
6
5
|
# tapyrus key class
|
7
6
|
class Key
|
8
|
-
|
9
7
|
PUBLIC_KEY_SIZE = 65
|
10
8
|
COMPRESSED_PUBLIC_KEY_SIZE = 33
|
11
9
|
SIGNATURE_SIZE = 72
|
@@ -18,9 +16,10 @@ module Tapyrus
|
|
18
16
|
attr_accessor :key_type
|
19
17
|
attr_reader :secp256k1_module
|
20
18
|
|
21
|
-
TYPES = {uncompressed: 0x00, compressed: 0x01, p2pkh: 0x10, p2wpkh: 0x11, p2wpkh_p2sh: 0x12}
|
19
|
+
TYPES = { uncompressed: 0x00, compressed: 0x01, p2pkh: 0x10, p2wpkh: 0x11, p2wpkh_p2sh: 0x12 }
|
22
20
|
|
23
21
|
MIN_PRIV_KEY_MOD_ORDER = 0x01
|
22
|
+
|
24
23
|
# Order of secp256k1's generator minus 1.
|
25
24
|
MAX_PRIV_KEY_MOD_ORDER = ECDSA::Group::Secp256k1.order - 1
|
26
25
|
|
@@ -31,18 +30,18 @@ module Tapyrus
|
|
31
30
|
# @param [Boolean] compressed [Deprecated] whether public key is compressed.
|
32
31
|
# @return [Tapyrus::Key] a key object.
|
33
32
|
def initialize(priv_key: nil, pubkey: nil, key_type: nil, compressed: true, allow_hybrid: false)
|
34
|
-
|
33
|
+
if key_type.nil? && !compressed.nil? && pubkey.nil?
|
34
|
+
puts '[Warning] Use key_type parameter instead of compressed. compressed parameter removed in the future.'
|
35
|
+
end
|
35
36
|
if key_type
|
36
37
|
@key_type = key_type
|
37
38
|
compressed = @key_type != TYPES[:uncompressed]
|
38
39
|
else
|
39
40
|
@key_type = compressed ? TYPES[:compressed] : TYPES[:uncompressed]
|
40
41
|
end
|
41
|
-
@secp256k1_module =
|
42
|
+
@secp256k1_module = Tapyrus.secp_impl
|
42
43
|
@priv_key = priv_key
|
43
|
-
if @priv_key
|
44
|
-
raise ArgumentError, Errors::Messages::INVALID_PRIV_KEY unless validate_private_key_range(@priv_key)
|
45
|
-
end
|
44
|
+
raise ArgumentError, Errors::Messages::INVALID_PRIV_KEY unless validate_private_key_range(@priv_key) if @priv_key
|
46
45
|
if pubkey
|
47
46
|
@pubkey = pubkey
|
48
47
|
else
|
@@ -66,7 +65,9 @@ module Tapyrus
|
|
66
65
|
data = hex[2...-8].htb
|
67
66
|
checksum = hex[-8..-1]
|
68
67
|
raise ArgumentError, 'invalid version' unless version == Tapyrus.chain_params.privkey_version
|
69
|
-
|
68
|
+
unless Tapyrus.calc_checksum(version + data.bth) == checksum
|
69
|
+
raise ArgumentError, Errors::Messages::INVALID_CHECKSUM
|
70
|
+
end
|
70
71
|
key_len = data.bytesize
|
71
72
|
if key_len == COMPRESSED_PUBLIC_KEY_SIZE && data[-1].unpack('C').first == 1
|
72
73
|
key_type = TYPES[:compressed]
|
@@ -95,7 +96,7 @@ module Tapyrus
|
|
95
96
|
# @param [Symbol] algo Algorithms used for verification. Either :ecdsa or :schnorr is supported. default value is :ecdsa.
|
96
97
|
# @return [String] signature data with binary format
|
97
98
|
def sign(data, low_r = true, extra_entropy = nil, algo: :ecdsa)
|
98
|
-
raise ArgumentError,
|
99
|
+
raise ArgumentError, 'Unsupported algorithm has been specified.' unless SIG_ALGO.include?(algo)
|
99
100
|
case algo
|
100
101
|
when :ecdsa
|
101
102
|
sign_ecdsa(data, low_r, extra_entropy)
|
@@ -114,7 +115,7 @@ module Tapyrus
|
|
114
115
|
def verify(sig, origin, algo: :ecdsa)
|
115
116
|
return false unless valid_pubkey?
|
116
117
|
begin
|
117
|
-
raise ArgumentError,
|
118
|
+
raise ArgumentError, 'Unsupported algorithm has been specified.' unless SIG_ALGO.include?(algo)
|
118
119
|
sig = ecdsa_signature_parse_der_lax(sig) if algo == :ecdsa
|
119
120
|
secp256k1_module.verify_sig(origin, sig, pubkey, algo: algo)
|
120
121
|
rescue Exception
|
@@ -150,12 +151,12 @@ module Tapyrus
|
|
150
151
|
p = pubkey.htb
|
151
152
|
return false if p.bytesize < COMPRESSED_PUBLIC_KEY_SIZE
|
152
153
|
case p[0]
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
154
|
+
when "\x04"
|
155
|
+
return false unless p.bytesize == PUBLIC_KEY_SIZE
|
156
|
+
when "\x02", "\x03"
|
157
|
+
return false unless p.bytesize == COMPRESSED_PUBLIC_KEY_SIZE
|
158
|
+
else
|
159
|
+
return false
|
159
160
|
end
|
160
161
|
true
|
161
162
|
end
|
@@ -172,16 +173,17 @@ module Tapyrus
|
|
172
173
|
len_r = s[3]
|
173
174
|
len_s = s[5 + len_r]
|
174
175
|
val_s = s.slice(6 + len_r, len_s)
|
176
|
+
|
177
|
+
# prettier-ignore
|
175
178
|
max_mod_half_order = [
|
176
|
-
0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
177
|
-
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
178
|
-
0x5d,0x57,0x6e,0x73,0x57,0xa4,0x50,0x1d,
|
179
|
-
0xdf,0xe9,0x2f,0x46,0x68,0x1b,0x20,0xa0
|
180
|
-
|
181
|
-
|
179
|
+
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
180
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
181
|
+
0x5d, 0x57, 0x6e, 0x73, 0x57, 0xa4, 0x50, 0x1d,
|
182
|
+
0xdf, 0xe9, 0x2f, 0x46, 0x68, 0x1b, 0x20, 0xa0
|
183
|
+
]
|
184
|
+
compare_big_endian(val_s, [0]) > 0 && compare_big_endian(val_s, max_mod_half_order) <= 0
|
182
185
|
end
|
183
186
|
|
184
|
-
|
185
187
|
# check +sig+ is correct der encoding.
|
186
188
|
# This function is consensus-critical since BIP66.
|
187
189
|
# @param [String] sig a signature data with binary format.
|
@@ -233,15 +235,11 @@ module Tapyrus
|
|
233
235
|
def self.compare_big_endian(c1, c2)
|
234
236
|
c1, c2 = c1.dup, c2.dup # Clone the arrays
|
235
237
|
|
236
|
-
while c1.size > c2.size
|
237
|
-
return 1 if c1.shift > 0
|
238
|
-
end
|
238
|
+
return 1 if c1.shift > 0 while c1.size > c2.size
|
239
239
|
|
240
|
-
while c2.size > c1.size
|
241
|
-
return -1 if c2.shift > 0
|
242
|
-
end
|
240
|
+
return -1 if c2.shift > 0 while c2.size > c1.size
|
243
241
|
|
244
|
-
c1.size.times{|idx| return c1[idx] - c2[idx] if c1[idx] != c2[idx] }
|
242
|
+
c1.size.times { |idx| return c1[idx] - c2[idx] if c1[idx] != c2[idx] }
|
245
243
|
0
|
246
244
|
end
|
247
245
|
|
@@ -267,7 +265,7 @@ module Tapyrus
|
|
267
265
|
def ecdsa_signature_parse_der_lax(sig)
|
268
266
|
sig_array = sig.unpack('C*')
|
269
267
|
len_r = sig_array[3]
|
270
|
-
r = sig_array[4...(len_r+4)].pack('C*').bth
|
268
|
+
r = sig_array[4...(len_r + 4)].pack('C*').bth
|
271
269
|
len_s = sig_array[len_r + 5]
|
272
270
|
s = sig_array[(len_r + 6)...(len_r + 6 + len_s)].pack('C*').bth
|
273
271
|
ECDSA::Signature.new(r.to_i(16), s.to_i(16)).to_der
|
@@ -291,13 +289,11 @@ module Tapyrus
|
|
291
289
|
counter = 1
|
292
290
|
until sig_has_low_r?(sig)
|
293
291
|
extra_entropy = [counter].pack('I*').bth.ljust(64, '0').htb
|
294
|
-
sig = secp256k1_module.sign_data(data, priv_key, extra_entropy,
|
292
|
+
sig = secp256k1_module.sign_data(data, priv_key, extra_entropy, algo: :ecdsa)
|
295
293
|
counter += 1
|
296
294
|
end
|
297
295
|
end
|
298
296
|
sig
|
299
297
|
end
|
300
|
-
|
301
298
|
end
|
302
|
-
|
303
299
|
end
|
data/lib/tapyrus/key_path.rb
CHANGED
@@ -1,26 +1,29 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module KeyPath
|
3
|
-
|
4
3
|
# key path convert an array of derive number
|
5
4
|
# @param [String] path_string
|
6
5
|
# @return [Array[Integer]] key path numbers.
|
7
6
|
def parse_key_path(path_string)
|
8
|
-
path_string
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
path_string
|
8
|
+
.split('/')
|
9
|
+
.map
|
10
|
+
.with_index do |p, index|
|
11
|
+
if index == 0
|
12
|
+
raise ArgumentError.new("#{path_string} is invalid format.") unless p == 'm'
|
13
|
+
next
|
14
|
+
end
|
15
|
+
raise ArgumentError.new("#{path_string} is invalid format.") unless p.delete("'") =~ /^[0-9]+$/
|
16
|
+
(p[-1] == "'" ? p.delete("'").to_i + Tapyrus::HARDENED_THRESHOLD : p.to_i)
|
17
|
+
end[
|
18
|
+
1..-1
|
19
|
+
]
|
16
20
|
end
|
17
21
|
|
18
22
|
# key path numbers convert to path string.
|
19
23
|
# @param [Array[Integer]] key path numbers.
|
20
24
|
# @return [String] path string.
|
21
25
|
def to_key_path(numbers)
|
22
|
-
"m/#{numbers.map{|p| p >= Tapyrus::HARDENED_THRESHOLD ? "#{p - Tapyrus::HARDENED_THRESHOLD}'" : p.to_s}.join('/')}"
|
26
|
+
"m/#{numbers.map { |p| p >= Tapyrus::HARDENED_THRESHOLD ? "#{p - Tapyrus::HARDENED_THRESHOLD}'" : p.to_s }.join('/')}"
|
23
27
|
end
|
24
|
-
|
25
28
|
end
|
26
|
-
end
|
29
|
+
end
|
data/lib/tapyrus/logger.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
3
|
module Tapyrus
|
4
|
-
|
5
4
|
# Simple Logger module
|
6
5
|
module Logger
|
7
|
-
|
8
6
|
Format = "%s, [%s#%d #%d] %5s -- %s: %s\n".freeze
|
9
7
|
|
10
8
|
module_function
|
@@ -15,28 +13,34 @@ module Tapyrus
|
|
15
13
|
FileUtils.mkdir_p(dir)
|
16
14
|
logger = ::Logger.new(dir + "/#{name}.log", 10)
|
17
15
|
logger.level = level
|
18
|
-
logger.formatter =
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
logger.formatter =
|
17
|
+
proc do |severity, datetime, progname, msg|
|
18
|
+
Format % [
|
19
|
+
severity[0..0],
|
20
|
+
format_datetime(datetime),
|
21
|
+
$$,
|
22
|
+
Thread.current.object_id,
|
23
|
+
severity,
|
24
|
+
progname,
|
25
|
+
msg2str(msg)
|
26
|
+
]
|
27
|
+
end
|
22
28
|
logger
|
23
29
|
end
|
24
30
|
|
25
31
|
def self.msg2str(msg)
|
26
32
|
case msg
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
msg.inspect
|
33
|
+
when ::String
|
34
|
+
msg
|
35
|
+
when ::Exception
|
36
|
+
"#{msg.message} (#{msg.class})\n" << (msg.backtrace || []).join("\n")
|
37
|
+
else
|
38
|
+
msg.inspect
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
37
42
|
def format_datetime(time)
|
38
|
-
time.strftime(@datetime_format ||
|
43
|
+
time.strftime(@datetime_format || '%Y-%m-%dT%H:%M:%S.%6N '.freeze)
|
39
44
|
end
|
40
|
-
|
41
45
|
end
|
42
|
-
end
|
46
|
+
end
|
data/lib/tapyrus/merkle_tree.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Tapyrus
|
2
|
-
|
3
2
|
# merkle tree
|
4
3
|
class MerkleTree
|
5
|
-
|
6
4
|
attr_accessor :root
|
7
5
|
|
8
6
|
def initialize(root = nil)
|
@@ -17,11 +15,12 @@ module Tapyrus
|
|
17
15
|
if txids.size == 1
|
18
16
|
nodes = [Node.new(txids.first)]
|
19
17
|
else
|
20
|
-
nodes =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
nodes =
|
19
|
+
txids.each_slice(2).map do |m|
|
20
|
+
left = Node.new(m[0])
|
21
|
+
right = Node.new(m[1] ? m[1] : m[0])
|
22
|
+
[left, right]
|
23
|
+
end.flatten
|
25
24
|
end
|
26
25
|
new(build_initial_tree(nodes))
|
27
26
|
end
|
@@ -29,7 +28,7 @@ module Tapyrus
|
|
29
28
|
# https://bitcoin.org/en/developer-reference#creating-a-merkleblock-message
|
30
29
|
def self.build_partial(tx_count, hashes, flags)
|
31
30
|
flags = flags.each_char.map(&:to_i)
|
32
|
-
root = build_initial_tree(
|
31
|
+
root = build_initial_tree(Array.new(tx_count) { Node.new })
|
33
32
|
current_node = root
|
34
33
|
hash_index = 0
|
35
34
|
flags.each do |f|
|
@@ -40,9 +39,7 @@ module Tapyrus
|
|
40
39
|
end
|
41
40
|
current_node = current_node.next_partial
|
42
41
|
if hash_index == hashes.size
|
43
|
-
if current_node&.leaf?
|
44
|
-
current_node.value = hashes.last
|
45
|
-
end
|
42
|
+
current_node.value = hashes.last if current_node&.leaf?
|
46
43
|
break
|
47
44
|
end
|
48
45
|
end
|
@@ -51,12 +48,15 @@ module Tapyrus
|
|
51
48
|
|
52
49
|
def self.build_initial_tree(nodes)
|
53
50
|
while nodes.size != 1
|
54
|
-
nodes =
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
nodes =
|
52
|
+
nodes
|
53
|
+
.each_slice(2)
|
54
|
+
.map do |m|
|
55
|
+
parent = Node.new
|
56
|
+
parent.left = m[0]
|
57
|
+
parent.right = m[1] ? m[1] : m[0].dup
|
58
|
+
parent
|
59
|
+
end
|
60
60
|
end
|
61
61
|
nodes.first
|
62
62
|
end
|
@@ -67,7 +67,6 @@ module Tapyrus
|
|
67
67
|
|
68
68
|
# node of merkle tree
|
69
69
|
class Node
|
70
|
-
|
71
70
|
attr_accessor :flag
|
72
71
|
attr_accessor :value
|
73
72
|
attr_accessor :parent
|
@@ -118,7 +117,7 @@ module Tapyrus
|
|
118
117
|
def depth
|
119
118
|
d = 0
|
120
119
|
current_node = self
|
121
|
-
until current_node.root?
|
120
|
+
until current_node.root?
|
122
121
|
current_node = current_node.parent
|
123
122
|
d += 1
|
124
123
|
end
|
@@ -137,7 +136,7 @@ module Tapyrus
|
|
137
136
|
i = 0
|
138
137
|
d = 1
|
139
138
|
current_node = self
|
140
|
-
until current_node.root?
|
139
|
+
until current_node.root?
|
141
140
|
i += d if current_node.parent.right == current_node
|
142
141
|
current_node = current_node.parent
|
143
142
|
d *= 2
|
data/lib/tapyrus/message.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
autoload :Base, 'tapyrus/message/base'
|
5
4
|
autoload :Inventory, 'tapyrus/message/inventory'
|
6
5
|
autoload :InventoriesParser, 'tapyrus/message/inventories_parser'
|
@@ -41,30 +40,29 @@ module Tapyrus
|
|
41
40
|
USER_AGENT = "/tapyrusrb:#{Tapyrus::VERSION}/"
|
42
41
|
|
43
42
|
SERVICE_FLAGS = {
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
none: 0,
|
44
|
+
network: 1 << 0, # the node is capable of serving the block chain. It is currently set by all Bitcoin Core node, and is unset by SPV clients or other peers that just want network services but don't provide them.
|
45
|
+
# getutxo: 1 << 1, # BIP-64. not implemented in Bitcoin Core.
|
46
|
+
bloom: 1 << 2 # the node is capable and willing to handle bloom-filtered connections. Bitcoin Core node used to support this by default, without advertising this bit, but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION)
|
47
|
+
#witness: 1 << 3, # the node can be asked for blocks and transactions including witness data.
|
48
|
+
# xthin: 1 << 4 # support Xtreme Thinblocks. not implemented in Bitcoin Core
|
50
49
|
}
|
51
50
|
|
52
51
|
# DEFAULT_SERVICE_FLAGS = SERVICE_FLAGS[:network] | SERVICE_FLAGS[:bloom] | SERVICE_FLAGS[:witness]
|
53
52
|
|
54
53
|
DEFAULT_SERVICE_FLAGS = SERVICE_FLAGS[:none]
|
55
54
|
|
56
|
-
DEFAULT_STOP_HASH =
|
55
|
+
DEFAULT_STOP_HASH = '00' * 32
|
57
56
|
|
58
57
|
# the protocol version.
|
59
58
|
VERSION = {
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
59
|
+
headers: 31_800,
|
60
|
+
pong: 60_001,
|
61
|
+
bloom: 70_011,
|
62
|
+
send_headers: 70_012,
|
63
|
+
fee_filter: 70_013,
|
64
|
+
compact: 70_014,
|
65
|
+
compact_witness: 70_015
|
67
66
|
}
|
68
|
-
|
69
67
|
end
|
70
68
|
end
|
data/lib/tapyrus/message/addr.rb
CHANGED
@@ -2,11 +2,9 @@ require 'ipaddr'
|
|
2
2
|
|
3
3
|
module Tapyrus
|
4
4
|
module Message
|
5
|
-
|
6
5
|
# addr message
|
7
6
|
# https://bitcoin.org/en/developer-reference#addr
|
8
7
|
class Addr < Base
|
9
|
-
|
10
8
|
COMMAND = 'addr'
|
11
9
|
|
12
10
|
attr_reader :addrs
|
@@ -19,17 +17,13 @@ module Tapyrus
|
|
19
17
|
buf = StringIO.new(payload)
|
20
18
|
addr_count = Tapyrus.unpack_var_int_from_io(buf)
|
21
19
|
addr = new
|
22
|
-
addr_count.times
|
23
|
-
addr.addrs << NetworkAddr.parse_from_payload(buf)
|
24
|
-
end
|
20
|
+
addr_count.times { addr.addrs << NetworkAddr.parse_from_payload(buf) }
|
25
21
|
addr
|
26
22
|
end
|
27
23
|
|
28
24
|
def to_payload
|
29
25
|
Tapyrus.pack_var_int(addrs.length) << addrs.map(&:to_payload).join
|
30
26
|
end
|
31
|
-
|
32
27
|
end
|
33
|
-
|
34
28
|
end
|
35
29
|
end
|
data/lib/tapyrus/message/base.rb
CHANGED