bitcoinrb 0.3.2 → 0.8.0
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/.rspec_parallel +2 -0
- data/.ruby-version +1 -1
- data/README.md +17 -6
- data/bitcoinrb.gemspec +9 -8
- data/exe/bitcoinrbd +5 -0
- data/lib/bitcoin.rb +37 -19
- data/lib/bitcoin/bip85_entropy.rb +111 -0
- data/lib/bitcoin/block_filter.rb +14 -0
- data/lib/bitcoin/block_header.rb +2 -0
- data/lib/bitcoin/chain_params.rb +9 -8
- data/lib/bitcoin/chainparams/regtest.yml +1 -1
- data/lib/bitcoin/chainparams/signet.yml +39 -0
- data/lib/bitcoin/chainparams/testnet.yml +1 -1
- data/lib/bitcoin/constants.rb +44 -10
- data/lib/bitcoin/descriptor.rb +1 -1
- data/lib/bitcoin/errors.rb +19 -0
- data/lib/bitcoin/ext.rb +6 -0
- data/lib/bitcoin/ext/array_ext.rb +22 -0
- data/lib/bitcoin/ext/ecdsa.rb +36 -0
- data/lib/bitcoin/ext/json_parser.rb +46 -0
- data/lib/bitcoin/ext_key.rb +51 -20
- data/lib/bitcoin/key.rb +89 -30
- data/lib/bitcoin/key_path.rb +12 -5
- data/lib/bitcoin/message.rb +79 -0
- data/lib/bitcoin/message/addr_v2.rb +34 -0
- data/lib/bitcoin/message/base.rb +17 -0
- data/lib/bitcoin/message/cf_parser.rb +16 -0
- data/lib/bitcoin/message/cfcheckpt.rb +36 -0
- data/lib/bitcoin/message/cfheaders.rb +40 -0
- data/lib/bitcoin/message/cfilter.rb +35 -0
- data/lib/bitcoin/message/fee_filter.rb +1 -1
- data/lib/bitcoin/message/filter_load.rb +3 -3
- data/lib/bitcoin/message/get_cfcheckpt.rb +29 -0
- data/lib/bitcoin/message/get_cfheaders.rb +24 -0
- data/lib/bitcoin/message/get_cfilters.rb +25 -0
- data/lib/bitcoin/message/header_and_short_ids.rb +1 -1
- data/lib/bitcoin/message/inventory.rb +1 -1
- data/lib/bitcoin/message/merkle_block.rb +1 -1
- data/lib/bitcoin/message/network_addr.rb +141 -18
- data/lib/bitcoin/message/ping.rb +1 -1
- data/lib/bitcoin/message/pong.rb +1 -1
- data/lib/bitcoin/message/send_addr_v2.rb +13 -0
- data/lib/bitcoin/message/send_cmpct.rb +2 -2
- data/lib/bitcoin/message/tx.rb +1 -1
- data/lib/bitcoin/message/version.rb +7 -0
- data/lib/bitcoin/message_sign.rb +47 -0
- data/lib/bitcoin/mnemonic.rb +7 -7
- data/lib/bitcoin/network/peer.rb +9 -4
- data/lib/bitcoin/network/peer_discovery.rb +1 -1
- data/lib/bitcoin/node/cli.rb +14 -10
- data/lib/bitcoin/node/configuration.rb +3 -1
- data/lib/bitcoin/node/spv.rb +9 -1
- data/lib/bitcoin/opcodes.rb +14 -1
- data/lib/bitcoin/out_point.rb +2 -0
- data/lib/bitcoin/payment_code.rb +92 -0
- data/lib/bitcoin/payments/payment.pb.rb +1 -1
- data/lib/bitcoin/psbt/hd_key_path.rb +1 -1
- data/lib/bitcoin/psbt/input.rb +9 -18
- data/lib/bitcoin/psbt/output.rb +1 -1
- data/lib/bitcoin/psbt/tx.rb +12 -17
- data/lib/bitcoin/rpc/bitcoin_core_client.rb +22 -12
- data/lib/bitcoin/rpc/request_handler.rb +5 -5
- data/lib/bitcoin/script/script.rb +96 -39
- data/lib/bitcoin/script/script_error.rb +27 -1
- data/lib/bitcoin/script/script_interpreter.rb +166 -66
- data/lib/bitcoin/script/tx_checker.rb +62 -14
- data/lib/bitcoin/secp256k1.rb +1 -0
- data/lib/bitcoin/secp256k1/native.rb +184 -17
- data/lib/bitcoin/secp256k1/rfc6979.rb +43 -0
- data/lib/bitcoin/secp256k1/ruby.rb +112 -56
- data/lib/bitcoin/sighash_generator.rb +156 -0
- data/lib/bitcoin/store.rb +1 -0
- data/lib/bitcoin/store/chain_entry.rb +1 -0
- data/lib/bitcoin/store/utxo_db.rb +226 -0
- data/lib/bitcoin/taproot.rb +9 -0
- data/lib/bitcoin/taproot/leaf_node.rb +23 -0
- data/lib/bitcoin/taproot/simple_builder.rb +139 -0
- data/lib/bitcoin/tx.rb +34 -104
- data/lib/bitcoin/tx_in.rb +4 -5
- data/lib/bitcoin/tx_out.rb +2 -3
- data/lib/bitcoin/util.rb +22 -6
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet.rb +1 -0
- data/lib/bitcoin/wallet/account.rb +2 -1
- data/lib/bitcoin/wallet/base.rb +2 -2
- data/lib/bitcoin/wallet/master_key.rb +1 -0
- data/lib/bitcoin/wallet/utxo.rb +37 -0
- metadata +86 -32
- data/.travis.yml +0 -11
@@ -0,0 +1,40 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# cfheaders message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#cfheaders
|
6
|
+
class CFHeaders < Base
|
7
|
+
|
8
|
+
COMMAND = 'cfheaders'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :stop_hash # little endian
|
12
|
+
attr_accessor :prev_filter_header # little endian
|
13
|
+
attr_accessor :filter_hashes # little endian
|
14
|
+
|
15
|
+
def initialize(filter_type, stop_hash, prev_filter_header, filter_hashes)
|
16
|
+
@filter_type = filter_type
|
17
|
+
@stop_hash = stop_hash
|
18
|
+
@prev_filter_header = prev_filter_header
|
19
|
+
@filter_hashes = filter_hashes
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.parse_from_payload(payload)
|
23
|
+
buf = StringIO.new(payload)
|
24
|
+
type = buf.read(1).unpack1("C")
|
25
|
+
hash = buf.read(32).bth
|
26
|
+
header = buf.read(32).bth
|
27
|
+
count = Bitcoin.unpack_var_int_from_io(buf)
|
28
|
+
hashes = count.times.map{buf.read(32).bth}
|
29
|
+
self.new(type, hash, header, hashes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_payload
|
33
|
+
[filter_type].pack('C') + stop_hash.htb + prev_filter_header.htb +
|
34
|
+
Bitcoin.pack_var_int(filter_hashes.size) + filter_hashes.map(&:htb).join
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# cfilter message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#cfilter
|
6
|
+
class CFilter < Base
|
7
|
+
|
8
|
+
COMMAND = 'cfilter'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :block_hash # little endian
|
12
|
+
attr_accessor :filter # little endian
|
13
|
+
|
14
|
+
def initialize(filter_type, block_hash, filter)
|
15
|
+
@filter_type = filter_type
|
16
|
+
@block_hash = block_hash
|
17
|
+
@filter = filter
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_from_payload(payload)
|
21
|
+
buf = StringIO.new(payload)
|
22
|
+
type = buf.read(1).unpack1("C")
|
23
|
+
hash = buf.read(32).bth
|
24
|
+
len = Bitcoin.unpack_var_int_from_io(buf)
|
25
|
+
filter = buf.read(len).bth
|
26
|
+
self.new(type, hash, filter)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_payload
|
30
|
+
[filter_type, block_hash].pack('CH*') + Bitcoin.pack_var_string(filter.htb)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -23,9 +23,9 @@ module Bitcoin
|
|
23
23
|
buf = StringIO.new(payload)
|
24
24
|
filter_count = Bitcoin.unpack_var_int_from_io(buf)
|
25
25
|
filter = buf.read(filter_count).unpack('C*')
|
26
|
-
func_count = buf.read(4).
|
27
|
-
tweak = buf.read(4).
|
28
|
-
flag = buf.read(1).
|
26
|
+
func_count = buf.read(4).unpack1('V')
|
27
|
+
tweak = buf.read(4).unpack1('V')
|
28
|
+
flag = buf.read(1).unpack1('C')
|
29
29
|
FilterLoad.new(Bitcoin::BloomFilter.new(filter, func_count, tweak), flag)
|
30
30
|
end
|
31
31
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# getcfcheckpt message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#getcfcheckpt
|
6
|
+
class GetCFCheckpt < Base
|
7
|
+
|
8
|
+
COMMAND = 'getcfcheckpt'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :stop_hash # little endian
|
12
|
+
|
13
|
+
def initialize(filter_type, stop_hash)
|
14
|
+
@filter_type = filter_type
|
15
|
+
@stop_hash = stop_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parse_from_payload(payload)
|
19
|
+
type, hash = payload.unpack('CH*')
|
20
|
+
self.new(type, hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_payload
|
24
|
+
[filter_type, stop_hash].pack('CH*')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# getcfheaders message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#getcfheaders
|
6
|
+
class GetCFHeaders < Base
|
7
|
+
include CFParser
|
8
|
+
extend CFParser
|
9
|
+
|
10
|
+
COMMAND = 'getcfheaders'
|
11
|
+
|
12
|
+
attr_accessor :filter_type
|
13
|
+
attr_accessor :start_height
|
14
|
+
attr_accessor :stop_hash # little endian
|
15
|
+
|
16
|
+
def initialize(filter_type, start_height, stop_hash)
|
17
|
+
@filter_type = filter_type
|
18
|
+
@start_height = start_height
|
19
|
+
@stop_hash = stop_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# getcfilters message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#getcfilters
|
6
|
+
class GetCFilters < Base
|
7
|
+
include CFParser
|
8
|
+
extend CFParser
|
9
|
+
|
10
|
+
COMMAND = 'getcfilters'
|
11
|
+
|
12
|
+
attr_accessor :filter_type
|
13
|
+
attr_accessor :start_height
|
14
|
+
attr_accessor :stop_hash # little endian
|
15
|
+
|
16
|
+
def initialize(filter_type, start_height, stop_hash)
|
17
|
+
@filter_type = filter_type
|
18
|
+
@start_height = start_height
|
19
|
+
@stop_hash = stop_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -22,7 +22,7 @@ module Bitcoin
|
|
22
22
|
def self.parse_from_payload(payload)
|
23
23
|
buf = StringIO.new(payload)
|
24
24
|
header = Bitcoin::BlockHeader.parse_from_payload(buf.read(80))
|
25
|
-
nonce = buf.read(8).
|
25
|
+
nonce = buf.read(8).unpack1('q*')
|
26
26
|
short_ids_len = Bitcoin.unpack_var_int_from_io(buf)
|
27
27
|
short_ids = short_ids_len.times.map do
|
28
28
|
buf.read(6).reverse.bth.to_i(16)
|
@@ -26,7 +26,7 @@ module Bitcoin
|
|
26
26
|
# parse inventory payload
|
27
27
|
def self.parse_from_payload(payload)
|
28
28
|
raise Error, 'invalid inventory size.' if payload.bytesize != 36
|
29
|
-
identifier = payload[0..4].
|
29
|
+
identifier = payload[0..4].unpack1('V')
|
30
30
|
hash = payload[4..-1].bth # internal byte order
|
31
31
|
new(identifier, hash)
|
32
32
|
end
|
@@ -20,7 +20,7 @@ module Bitcoin
|
|
20
20
|
m = new
|
21
21
|
buf = StringIO.new(payload)
|
22
22
|
m.header = Bitcoin::BlockHeader.parse_from_payload(buf.read(80))
|
23
|
-
m.tx_count = buf.read(4).
|
23
|
+
m.tx_count = buf.read(4).unpack1('V')
|
24
24
|
hash_count = Bitcoin.unpack_var_int_from_io(buf)
|
25
25
|
hash_count.times do
|
26
26
|
m.hashes << buf.read(32).bth
|
@@ -1,10 +1,16 @@
|
|
1
1
|
require 'ipaddr'
|
2
|
+
require 'base32'
|
2
3
|
|
3
4
|
module Bitcoin
|
4
5
|
module Message
|
5
6
|
|
7
|
+
NETWORK_ID = {ipv4: 0x01, ipv6: 0x02, tor_v2: 0x03, tor_v3: 0x04, i2p: 0x05, cjdns: 0x06}
|
8
|
+
INTERNAL_IN_IPV6_PREFIX = "fd6b:88c0:8724"
|
9
|
+
|
6
10
|
class NetworkAddr
|
7
11
|
|
12
|
+
TYPE = {legacy: 0x01, addr_v2: 0x02}
|
13
|
+
|
8
14
|
# unix time.
|
9
15
|
# Nodes advertising their own IP address set this to the current time.
|
10
16
|
# Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
|
@@ -14,47 +20,164 @@ module Bitcoin
|
|
14
20
|
# The services the node advertised in its version message.
|
15
21
|
attr_accessor :services
|
16
22
|
|
17
|
-
attr_accessor :
|
23
|
+
attr_accessor :net # network ID that defined by BIP-155
|
24
|
+
|
25
|
+
# Network address. The interpretation depends on networkID.
|
26
|
+
# If ipv4 or ipv6 this field is a IPAddr object, otherwise hex string.
|
27
|
+
attr_accessor :addr
|
18
28
|
|
19
29
|
attr_accessor :port
|
20
30
|
|
21
31
|
attr_reader :skip_time
|
22
32
|
|
23
|
-
def initialize(ip: '127.0.0.1', port: Bitcoin.chain_params.default_port,
|
33
|
+
def initialize(ip: '127.0.0.1', port: Bitcoin.chain_params.default_port,
|
34
|
+
services: DEFAULT_SERVICE_FLAGS, time: Time.now.to_i, net: NETWORK_ID[:ipv4])
|
24
35
|
@time = time
|
25
|
-
@ip_addr = IPAddr.new(ip)
|
26
36
|
@port = port
|
27
37
|
@services = services
|
38
|
+
@net = net
|
39
|
+
case net
|
40
|
+
when NETWORK_ID[:ipv4], NETWORK_ID[:ipv6]
|
41
|
+
@addr = IPAddr.new(ip) if ip
|
42
|
+
end
|
28
43
|
end
|
29
44
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
45
|
+
# Parse addr payload
|
46
|
+
# @param [String] payload payload of addr
|
47
|
+
# @param [Integer] type Address format type
|
48
|
+
# @return [NetworkAddr]
|
49
|
+
def self.parse_from_payload(payload, type: TYPE[:legacy])
|
50
|
+
case type
|
51
|
+
when TYPE[:legacy]
|
52
|
+
load_legacy_payload(payload)
|
53
|
+
when TYPE[:addr_v2]
|
54
|
+
load_addr_v2_payload(payload)
|
55
|
+
else
|
56
|
+
raise Bitcoin::Message::Error, "Unknown type: #{type}."
|
57
|
+
end
|
39
58
|
end
|
40
59
|
|
41
60
|
def self.local_addr
|
42
61
|
addr = new
|
43
|
-
addr.
|
62
|
+
addr.addr = IPAddr.new('127.0.0.1')
|
44
63
|
addr.port = Bitcoin.chain_params.default_port
|
45
64
|
addr.services = DEFAULT_SERVICE_FLAGS
|
46
65
|
addr
|
47
66
|
end
|
48
67
|
|
49
|
-
|
50
|
-
|
68
|
+
# Show addr string. e.g 127.0.0.1
|
69
|
+
def addr_string
|
70
|
+
case net
|
71
|
+
when NETWORK_ID[:ipv4]
|
72
|
+
addr.native
|
73
|
+
when NETWORK_ID[:ipv6]
|
74
|
+
if addr.to_s.start_with?(INTERNAL_IN_IPV6_PREFIX)
|
75
|
+
Base32.encode(addr.hton[6..-1]).downcase.delete('=') + ".internal"
|
76
|
+
else
|
77
|
+
addr.to_s
|
78
|
+
end
|
79
|
+
when NETWORK_ID[:tor_v2]
|
80
|
+
Base32.encode(addr.htb).downcase + ".onion"
|
81
|
+
when NETWORK_ID[:tor_v3]
|
82
|
+
# TORv3 onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion"
|
83
|
+
pubkey = addr.htb
|
84
|
+
checksum = OpenSSL::Digest.new('SHA3-256').digest('.onion checksum' + pubkey + "\x03")
|
85
|
+
Base32.encode(pubkey + checksum[0...2] + "\x03").downcase + ".onion"
|
86
|
+
when NETWORK_ID[:i2p]
|
87
|
+
Base32.encode(addr.htb).downcase.delete('=') + ".b32.i2p"
|
88
|
+
when NETWORK_ID[:cjdns]
|
89
|
+
addr.to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_payload(skip_time = false, type: TYPE[:legacy])
|
94
|
+
case type
|
95
|
+
when TYPE[:legacy]
|
96
|
+
legacy_payload(skip_time)
|
97
|
+
when TYPE[:addr_v2]
|
98
|
+
v2_payload
|
99
|
+
else
|
100
|
+
raise Bitcoin::Message::Error, "Unknown type: #{type}."
|
101
|
+
end
|
51
102
|
end
|
52
103
|
|
53
|
-
|
104
|
+
# Load addr payload with legacy format.
|
105
|
+
def self.load_legacy_payload(payload)
|
106
|
+
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
107
|
+
has_time = buf.size > 26
|
108
|
+
addr = NetworkAddr.new(time: nil)
|
109
|
+
addr.time = buf.read(4).unpack1('V') if has_time
|
110
|
+
addr.services = buf.read(8).unpack1('Q')
|
111
|
+
addr.addr = IPAddr::new_ntoh(buf.read(16))
|
112
|
+
addr.port = buf.read(2).unpack1('n')
|
113
|
+
addr
|
114
|
+
end
|
115
|
+
|
116
|
+
# Load addr payload with addr v2 format.
|
117
|
+
def self.load_addr_v2_payload(payload)
|
118
|
+
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
119
|
+
addr = NetworkAddr.new(time: buf.read(4).unpack1('V'))
|
120
|
+
addr.services = Bitcoin.unpack_var_int_from_io(buf)
|
121
|
+
addr.net = buf.read(1).unpack1('C')
|
122
|
+
raise Bitcoin::Message::Error, "Unknown network id: #{addr.net}" unless NETWORK_ID.value?(addr.net)
|
123
|
+
addr_len = Bitcoin.unpack_var_int_from_io(buf)
|
124
|
+
addr.addr = case addr.net
|
125
|
+
when NETWORK_ID[:ipv4]
|
126
|
+
raise Bitcoin::Message::Error, "Invalid IPv4 address." unless addr_len == 4
|
127
|
+
IPAddr::new_ntoh(buf.read(addr_len))
|
128
|
+
when NETWORK_ID[:ipv6]
|
129
|
+
raise Bitcoin::Message::Error, "Invalid IPv6 address." unless addr_len == 16
|
130
|
+
a = IPAddr::new_ntoh(buf.read(addr_len))
|
131
|
+
raise Bitcoin::Message::Error, "Invalid IPv6 address." if a.ipv4_mapped?
|
132
|
+
a
|
133
|
+
when NETWORK_ID[:tor_v2]
|
134
|
+
raise Bitcoin::Message::Error, "Invalid Tor v2 address." unless addr_len == 10
|
135
|
+
buf.read(addr_len).bth
|
136
|
+
when NETWORK_ID[:tor_v3]
|
137
|
+
raise Bitcoin::Message::Error, "Invalid Tor v3 address." unless addr_len == 32
|
138
|
+
buf.read(addr_len).bth
|
139
|
+
when NETWORK_ID[:i2p]
|
140
|
+
raise Bitcoin::Message::Error, "Invalid I2P address." unless addr_len == 32
|
141
|
+
buf.read(addr_len).bth
|
142
|
+
when NETWORK_ID[:cjdns]
|
143
|
+
raise Bitcoin::Message::Error, "Invalid CJDNS address." unless addr_len == 16
|
144
|
+
a = IPAddr::new_ntoh(buf.read(addr_len))
|
145
|
+
raise Bitcoin::Message::Error, "Invalid CJDNS address." unless a.to_s.start_with?('fc00:')
|
146
|
+
a
|
147
|
+
end
|
148
|
+
addr.port = buf.read(2).unpack1('n')
|
149
|
+
addr
|
150
|
+
end
|
151
|
+
|
152
|
+
def legacy_payload(skip_time)
|
54
153
|
p = ''
|
55
154
|
p << [time].pack('V') unless skip_time
|
56
|
-
|
57
|
-
p << [services].pack('Q') <<
|
155
|
+
ip = addr.ipv4? ? addr.ipv4_mapped : addr
|
156
|
+
p << [services].pack('Q') << ip.hton << [port].pack('n')
|
157
|
+
end
|
158
|
+
|
159
|
+
def v2_payload
|
160
|
+
p = [time].pack('V')
|
161
|
+
p << Bitcoin.pack_var_int(services)
|
162
|
+
p << [net].pack('C')
|
163
|
+
case net
|
164
|
+
when NETWORK_ID[:ipv4]
|
165
|
+
p << Bitcoin.pack_var_int(4)
|
166
|
+
p << addr.to_i.to_s(16).htb
|
167
|
+
when NETWORK_ID[:ipv6]
|
168
|
+
p << Bitcoin.pack_var_int(16)
|
169
|
+
p << addr.hton
|
170
|
+
when NETWORK_ID[:tor_v2]
|
171
|
+
p << Bitcoin.pack_var_int(10)
|
172
|
+
when NETWORK_ID[:tor_v3]
|
173
|
+
p << Bitcoin.pack_var_int(32)
|
174
|
+
when NETWORK_ID[:i2p]
|
175
|
+
p << Bitcoin.pack_var_int(32)
|
176
|
+
when NETWORK_ID[:cjdns]
|
177
|
+
p << Bitcoin.pack_var_int(16)
|
178
|
+
end
|
179
|
+
p << [port].pack('n')
|
180
|
+
p
|
58
181
|
end
|
59
182
|
|
60
183
|
end
|
data/lib/bitcoin/message/ping.rb
CHANGED
data/lib/bitcoin/message/pong.rb
CHANGED