tapyrus 0.2.7 → 0.2.12
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/.ruby-version +1 -1
- data/CODE_OF_CONDUCT.md +7 -7
- data/README.md +14 -17
- data/Rakefile +3 -3
- data/lib/openassets/marker_output.rb +0 -4
- data/lib/openassets/payload.rb +4 -10
- data/lib/openassets.rb +0 -2
- data/lib/schnorr/sign_to_contract.rb +51 -0
- data/lib/schnorr/signature.rb +3 -6
- data/lib/schnorr.rb +14 -9
- data/lib/tapyrus/base58.rb +7 -6
- data/lib/tapyrus/bip175.rb +78 -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/ecdsa.rb +4 -4
- data/lib/tapyrus/ext/json_parser.rb +1 -4
- data/lib/tapyrus/ext.rb +1 -1
- 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 +22 -20
- 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/message.rb +14 -16
- data/lib/tapyrus/mnemonic.rb +17 -15
- 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 +10 -9
- data/lib/tapyrus/network/pool.rb +12 -12
- data/lib/tapyrus/network.rb +0 -2
- 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/node.rb +1 -1
- data/lib/tapyrus/opcodes.rb +9 -7
- data/lib/tapyrus/out_point.rb +5 -5
- data/lib/tapyrus/rpc/http_server.rb +21 -22
- data/lib/tapyrus/rpc/request_handler.rb +16 -21
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +67 -25
- data/lib/tapyrus/rpc.rb +1 -0
- data/lib/tapyrus/script/color.rb +10 -0
- data/lib/tapyrus/script/multisig.rb +13 -12
- data/lib/tapyrus/script/script.rb +93 -88
- 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/native.rb +14 -15
- data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
- data/lib/tapyrus/secp256k1/ruby.rb +10 -12
- data/lib/tapyrus/secp256k1.rb +0 -4
- data/lib/tapyrus/slip39/share.rb +41 -29
- data/lib/tapyrus/slip39/sss.rb +92 -49
- data/lib/tapyrus/slip39.rb +20 -5
- data/lib/tapyrus/store/chain_entry.rb +0 -4
- data/lib/tapyrus/store/db/level_db.rb +5 -9
- data/lib/tapyrus/store/db.rb +0 -2
- data/lib/tapyrus/store/spv_chain.rb +11 -17
- data/lib/tapyrus/store.rb +1 -3
- data/lib/tapyrus/tx.rb +45 -37
- data/lib/tapyrus/tx_builder.rb +160 -0
- data/lib/tapyrus/tx_in.rb +1 -6
- data/lib/tapyrus/tx_out.rb +2 -7
- data/lib/tapyrus/util.rb +7 -9
- 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/lib/tapyrus.rb +7 -22
- data/tapyrusrb.gemspec +13 -14
- metadata +26 -7
- data/.travis.yml +0 -14
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# merckleblock message
|
5
4
|
# https://bitcoin.org/en/developer-reference#merkleblock
|
6
5
|
class MerkleBlock < Base
|
7
|
-
|
8
6
|
COMMAND = 'merkleblock'
|
9
7
|
|
10
8
|
attr_accessor :header
|
@@ -22,21 +20,18 @@ module Tapyrus
|
|
22
20
|
m.header = Tapyrus::BlockHeader.parse_from_payload(buf)
|
23
21
|
m.tx_count = buf.read(4).unpack('V').first
|
24
22
|
hash_count = Tapyrus.unpack_var_int_from_io(buf)
|
25
|
-
hash_count.times
|
26
|
-
m.hashes << buf.read(32).bth
|
27
|
-
end
|
23
|
+
hash_count.times { m.hashes << buf.read(32).bth }
|
28
24
|
flag_count = Tapyrus.unpack_var_int_from_io(buf)
|
25
|
+
|
29
26
|
# A sequence of bits packed eight in a byte with the least significant bit first.
|
30
27
|
m.flags = buf.read(flag_count).bth
|
31
28
|
m
|
32
29
|
end
|
33
30
|
|
34
31
|
def to_payload
|
35
|
-
header.to_payload << [tx_count].pack('V') << Tapyrus.pack_var_int(hashes.size) <<
|
36
|
-
|
32
|
+
header.to_payload << [tx_count].pack('V') << Tapyrus.pack_var_int(hashes.size) << hashes.map(&:htb).join <<
|
33
|
+
Tapyrus.pack_var_int(flags.htb.bytesize) << flags.htb
|
37
34
|
end
|
38
|
-
|
39
35
|
end
|
40
|
-
|
41
36
|
end
|
42
37
|
end
|
@@ -2,9 +2,7 @@ require 'ipaddr'
|
|
2
2
|
|
3
3
|
module Tapyrus
|
4
4
|
module Message
|
5
|
-
|
6
5
|
class NetworkAddr
|
7
|
-
|
8
6
|
# unix time.
|
9
7
|
# Nodes advertising their own IP address set this to the current time.
|
10
8
|
# Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
|
@@ -20,7 +18,12 @@ module Tapyrus
|
|
20
18
|
|
21
19
|
attr_reader :skip_time
|
22
20
|
|
23
|
-
def initialize(
|
21
|
+
def initialize(
|
22
|
+
ip: '127.0.0.1',
|
23
|
+
port: Tapyrus.chain_params.default_port,
|
24
|
+
services: DEFAULT_SERVICE_FLAGS,
|
25
|
+
time: Time.now.to_i
|
26
|
+
)
|
24
27
|
@time = time
|
25
28
|
@ip_addr = IPAddr.new(ip)
|
26
29
|
@port = port
|
@@ -33,7 +36,7 @@ module Tapyrus
|
|
33
36
|
addr = new(time: nil)
|
34
37
|
addr.time = buf.read(4).unpack('V').first if has_time
|
35
38
|
addr.services = buf.read(8).unpack('Q').first
|
36
|
-
addr.ip_addr = IPAddr
|
39
|
+
addr.ip_addr = IPAddr.new_ntoh(buf.read(16))
|
37
40
|
addr.port = buf.read(2).unpack('n').first
|
38
41
|
addr
|
39
42
|
end
|
@@ -56,8 +59,6 @@ module Tapyrus
|
|
56
59
|
addr = ip_addr.ipv4? ? ip_addr.ipv4_mapped : ip_addr
|
57
60
|
p << [services].pack('Q') << addr.hton << [port].pack('n')
|
58
61
|
end
|
59
|
-
|
60
62
|
end
|
61
|
-
|
62
63
|
end
|
63
64
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# notfound message
|
5
4
|
# https://bitcoin.org/en/developer-reference#notfound
|
6
5
|
class NotFound < Base
|
@@ -14,8 +13,6 @@ module Tapyrus
|
|
14
13
|
def initialize(inventories = [])
|
15
14
|
@inventories = inventories
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
20
|
-
|
21
18
|
end
|
data/lib/tapyrus/message/ping.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# ping message class
|
5
4
|
# https://bitcoin.org/en/developer-reference#ping
|
6
5
|
class Ping < Base
|
7
|
-
|
8
6
|
COMMAND = 'ping'
|
9
7
|
|
10
8
|
attr_accessor :nonce
|
@@ -24,7 +22,6 @@ module Tapyrus
|
|
24
22
|
def to_response
|
25
23
|
Pong.new(nonce)
|
26
24
|
end
|
27
|
-
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
data/lib/tapyrus/message/pong.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# pong message
|
5
4
|
# https://bitcoin.org/en/developer-reference#pong
|
6
5
|
class Pong < Base
|
7
|
-
|
8
6
|
COMMAND = 'pong'
|
9
7
|
|
10
8
|
attr_reader :nonce
|
@@ -21,6 +19,5 @@ module Tapyrus
|
|
21
19
|
[nonce].pack('Q')
|
22
20
|
end
|
23
21
|
end
|
24
|
-
|
25
22
|
end
|
26
23
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# A PrefilledTransaction structure is used in HeaderAndShortIDs to provide a list of a few transactions explicitly.
|
5
4
|
# https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
|
6
5
|
class PrefilledTx
|
7
|
-
|
8
6
|
attr_accessor :index
|
9
7
|
attr_accessor :tx
|
10
8
|
|
@@ -22,8 +20,6 @@ module Tapyrus
|
|
22
20
|
def to_payload
|
23
21
|
Tapyrus.pack_var_int(index) << tx.to_payload
|
24
22
|
end
|
25
|
-
|
26
23
|
end
|
27
|
-
|
28
24
|
end
|
29
25
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# reject message
|
5
4
|
# https://bitcoin.org/en/developer-reference#reject
|
6
5
|
class Reject < Base
|
7
|
-
|
8
6
|
attr_accessor :message
|
9
7
|
attr_accessor :code
|
10
8
|
attr_accessor :reason
|
@@ -40,7 +38,6 @@ module Tapyrus
|
|
40
38
|
e = ['tx', 'block'].include?(message) ? extra.htb : extra
|
41
39
|
Tapyrus.pack_var_string(message) << [code].pack('C') << Tapyrus.pack_var_string(reason) << e
|
42
40
|
end
|
43
|
-
|
44
41
|
end
|
45
42
|
end
|
46
43
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# sendcmpct message
|
5
4
|
# https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
|
6
5
|
class SendCmpct < Base
|
7
|
-
|
8
6
|
COMMAND = 'sendcmpct'
|
9
7
|
|
10
8
|
MODE_HIGH = 1
|
@@ -12,6 +10,7 @@ module Tapyrus
|
|
12
10
|
|
13
11
|
attr_accessor :mode
|
14
12
|
attr_accessor :version
|
13
|
+
|
15
14
|
# TODO support version 2
|
16
15
|
|
17
16
|
def initialize(mode = MODE_HIGH, version = 1)
|
@@ -38,6 +37,5 @@ module Tapyrus
|
|
38
37
|
mode.zero?
|
39
38
|
end
|
40
39
|
end
|
41
|
-
|
42
40
|
end
|
43
41
|
end
|
data/lib/tapyrus/message/tx.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# tx message
|
5
4
|
# https://bitcoin.org/en/developer-reference#tx
|
6
5
|
class Tx < Base
|
7
|
-
|
8
6
|
COMMAND = 'tx'
|
9
7
|
|
10
8
|
attr_accessor :tx
|
@@ -23,8 +21,6 @@ module Tapyrus
|
|
23
21
|
def to_payload
|
24
22
|
tx.to_payload
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
28
|
-
|
29
25
|
end
|
30
26
|
end
|
@@ -2,10 +2,8 @@
|
|
2
2
|
require 'ipaddr'
|
3
3
|
module Tapyrus
|
4
4
|
module Message
|
5
|
-
|
6
5
|
# https://bitcoin.org/en/developer-reference#version
|
7
6
|
class Version < Base
|
8
|
-
|
9
7
|
COMMAND = 'version'
|
10
8
|
|
11
9
|
attr_accessor :version
|
@@ -61,9 +59,8 @@ module Tapyrus
|
|
61
59
|
end
|
62
60
|
|
63
61
|
def unpack_relay_field(payload)
|
64
|
-
(
|
62
|
+
(version >= 70_001 && payload) ? unpack_boolean(payload) : [true, nil]
|
65
63
|
end
|
66
|
-
|
67
64
|
end
|
68
65
|
end
|
69
|
-
end
|
66
|
+
end
|
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/mnemonic.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tapyrus
|
2
|
-
|
3
2
|
# Mnemonic code for generating deterministic keys
|
4
3
|
# https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
5
4
|
class Mnemonic
|
6
|
-
|
7
5
|
WORD_DIR = "#{__dir__}/mnemonic/wordlist"
|
8
6
|
|
9
7
|
attr_reader :word_list
|
@@ -15,7 +13,7 @@ module Tapyrus
|
|
15
13
|
|
16
14
|
# get support language list
|
17
15
|
def self.word_lists
|
18
|
-
Dir.glob("#{WORD_DIR}/**.txt").map{|f| f.gsub("#{WORD_DIR}/", '').gsub('.txt', '') }
|
16
|
+
Dir.glob("#{WORD_DIR}/**.txt").map { |f| f.gsub("#{WORD_DIR}/", '').gsub('.txt', '') }
|
19
17
|
end
|
20
18
|
|
21
19
|
# generate entropy from mnemonic word
|
@@ -23,11 +21,12 @@ module Tapyrus
|
|
23
21
|
# @return [String] an entropy with hex format.
|
24
22
|
def to_entropy(words)
|
25
23
|
word_master = load_words
|
26
|
-
mnemonic =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
mnemonic =
|
25
|
+
words.map do |w|
|
26
|
+
index = word_master.index(w.downcase)
|
27
|
+
raise IndexError, 'word not found in words list.' unless index
|
28
|
+
index.to_s(2).rjust(11, '0')
|
29
|
+
end.join
|
31
30
|
entropy = mnemonic.slice(0, (mnemonic.length * 32) / 33)
|
32
31
|
checksum = mnemonic.gsub(entropy, '')
|
33
32
|
raise SecurityError, 'checksum mismatch.' unless checksum == checksum(entropy)
|
@@ -41,9 +40,9 @@ module Tapyrus
|
|
41
40
|
raise ArgumentError, 'entropy is empty.' if entropy.nil? || entropy.empty?
|
42
41
|
e = entropy.htb.unpack('B*').first
|
43
42
|
seed = e + checksum(e)
|
44
|
-
mnemonic_index = seed.chars.each_slice(11).map{|i|i.join.to_i(2)}
|
43
|
+
mnemonic_index = seed.chars.each_slice(11).map { |i| i.join.to_i(2) }
|
45
44
|
word_master = load_words
|
46
|
-
mnemonic_index.map{|i|word_master[i]}
|
45
|
+
mnemonic_index.map { |i| word_master[i] }
|
47
46
|
end
|
48
47
|
|
49
48
|
# generate seed from mnemonic
|
@@ -53,8 +52,13 @@ module Tapyrus
|
|
53
52
|
# @return [String] seed
|
54
53
|
def to_seed(mnemonic, passphrase: '')
|
55
54
|
to_entropy(mnemonic)
|
56
|
-
OpenSSL::PKCS5.pbkdf2_hmac(
|
57
|
-
|
55
|
+
OpenSSL::PKCS5.pbkdf2_hmac(
|
56
|
+
mnemonic.join(' ').downcase,
|
57
|
+
'mnemonic' + passphrase,
|
58
|
+
2048,
|
59
|
+
64,
|
60
|
+
OpenSSL::Digest::SHA512.new
|
61
|
+
).bth
|
58
62
|
end
|
59
63
|
|
60
64
|
# calculate entropy checksum
|
@@ -62,7 +66,7 @@ module Tapyrus
|
|
62
66
|
# @return [String] an entropy checksum with bit string format
|
63
67
|
def checksum(entropy)
|
64
68
|
b = Tapyrus.sha256([entropy].pack('B*')).unpack('B*').first
|
65
|
-
b.slice(0, (entropy.length/32))
|
69
|
+
b.slice(0, (entropy.length / 32))
|
66
70
|
end
|
67
71
|
|
68
72
|
private
|
@@ -71,7 +75,5 @@ module Tapyrus
|
|
71
75
|
def load_words
|
72
76
|
File.readlines("#{WORD_DIR}/#{word_list}.txt").map(&:strip)
|
73
77
|
end
|
74
|
-
|
75
78
|
end
|
76
|
-
|
77
79
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Network
|
3
|
-
|
4
3
|
# P2P message handler used by peer connection class.
|
5
4
|
module MessageHandler
|
6
|
-
|
7
5
|
# handle p2p message.
|
8
6
|
def handle(message)
|
9
7
|
peer.last_recv = Time.now.to_i
|
@@ -22,7 +20,7 @@ module Tapyrus
|
|
22
20
|
return unless command
|
23
21
|
|
24
22
|
defer_handle_command(command, payload)
|
25
|
-
@message =
|
23
|
+
@message = ''
|
26
24
|
parse(rest) if rest && rest.bytesize > 0
|
27
25
|
end
|
28
26
|
|
@@ -35,7 +33,9 @@ module Tapyrus
|
|
35
33
|
|
36
34
|
payload = @message[MESSAGE_HEADER_SIZE...(MESSAGE_HEADER_SIZE + length)]
|
37
35
|
return if payload.size < length
|
38
|
-
|
36
|
+
unless Tapyrus.double_sha256(payload)[0...4] == checksum
|
37
|
+
raise Tapyrus::Message::Error, "header checksum mismatch. #{checksum.bth}"
|
38
|
+
end
|
39
39
|
|
40
40
|
rest = @message[(MESSAGE_HEADER_SIZE + length)..-1]
|
41
41
|
[command, payload, rest]
|
@@ -43,62 +43,63 @@ module Tapyrus
|
|
43
43
|
|
44
44
|
# handle command with EM#defer
|
45
45
|
def defer_handle_command(command, payload)
|
46
|
-
operation = proc {handle_command(command, payload)}
|
47
|
-
callback = proc{|result|}
|
48
|
-
errback =
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
operation = proc { handle_command(command, payload) }
|
47
|
+
callback = proc { |result| }
|
48
|
+
errback =
|
49
|
+
proc do |e|
|
50
|
+
logger.error("error occurred. #{e.message}")
|
51
|
+
logger.error(e.backtrace)
|
52
|
+
peer.handle_error(e)
|
53
|
+
end
|
53
54
|
EM.defer(operation, callback, errback)
|
54
55
|
end
|
55
56
|
|
56
57
|
def handle_command(command, payload)
|
57
58
|
logger.info("[#{addr}] process command #{command}.")
|
58
59
|
case command
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
60
|
+
when Tapyrus::Message::Version::COMMAND
|
61
|
+
on_version(Tapyrus::Message::Version.parse_from_payload(payload))
|
62
|
+
when Tapyrus::Message::VerAck::COMMAND
|
63
|
+
on_ver_ack
|
64
|
+
when Tapyrus::Message::GetAddr::COMMAND
|
65
|
+
on_get_addr
|
66
|
+
when Tapyrus::Message::Addr::COMMAND
|
67
|
+
on_addr(Tapyrus::Message::Addr.parse_from_payload(payload))
|
68
|
+
when Tapyrus::Message::SendHeaders::COMMAND
|
69
|
+
on_send_headers
|
70
|
+
when Tapyrus::Message::FeeFilter::COMMAND
|
71
|
+
on_fee_filter(Tapyrus::Message::FeeFilter.parse_from_payload(payload))
|
72
|
+
when Tapyrus::Message::Ping::COMMAND
|
73
|
+
on_ping(Tapyrus::Message::Ping.parse_from_payload(payload))
|
74
|
+
when Tapyrus::Message::Pong::COMMAND
|
75
|
+
on_pong(Tapyrus::Message::Pong.parse_from_payload(payload))
|
76
|
+
when Tapyrus::Message::GetHeaders::COMMAND
|
77
|
+
on_get_headers(Tapyrus::Message::GetHeaders.parse_from_payload(payload))
|
78
|
+
when Tapyrus::Message::Headers::COMMAND
|
79
|
+
on_headers(Tapyrus::Message::Headers.parse_from_payload(payload))
|
80
|
+
when Tapyrus::Message::Block::COMMAND
|
81
|
+
on_block(Tapyrus::Message::Block.parse_from_payload(payload))
|
82
|
+
when Tapyrus::Message::Tx::COMMAND
|
83
|
+
on_tx(Tapyrus::Message::Tx.parse_from_payload(payload))
|
84
|
+
when Tapyrus::Message::NotFound::COMMAND
|
85
|
+
on_not_found(Tapyrus::Message::NotFound.parse_from_payload(payload))
|
86
|
+
when Tapyrus::Message::MemPool::COMMAND
|
87
|
+
on_mem_pool
|
88
|
+
when Tapyrus::Message::Reject::COMMAND
|
89
|
+
on_reject(Tapyrus::Message::Reject.parse_from_payload(payload))
|
90
|
+
when Tapyrus::Message::SendCmpct::COMMAND
|
91
|
+
on_send_cmpct(Tapyrus::Message::SendCmpct.parse_from_payload(payload))
|
92
|
+
when Tapyrus::Message::Inv::COMMAND
|
93
|
+
on_inv(Tapyrus::Message::Inv.parse_from_payload(payload))
|
94
|
+
when Tapyrus::Message::MerkleBlock::COMMAND
|
95
|
+
on_merkle_block(Tapyrus::Message::MerkleBlock.parse_from_payload(payload))
|
96
|
+
when Tapyrus::Message::CmpctBlock::COMMAND
|
97
|
+
on_cmpct_block(Tapyrus::Message::CmpctBlock.parse_from_payload(payload))
|
98
|
+
when Tapyrus::Message::GetData::COMMAND
|
99
|
+
on_get_data(Tapyrus::Message::GetData.parse_from_payload(payload))
|
100
|
+
else
|
101
|
+
logger.warn("unsupported command received. command: #{command}, payload: #{payload.bth}")
|
102
|
+
close("with command #{command}")
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
@@ -212,12 +213,12 @@ module Tapyrus
|
|
212
213
|
txs = []
|
213
214
|
inv.inventories.each do |i|
|
214
215
|
case i.identifier
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
216
|
+
when Tapyrus::Message::Inventory::MSG_TX
|
217
|
+
txs << i.hash
|
218
|
+
when Tapyrus::Message::Inventory::MSG_BLOCK
|
219
|
+
blocks << i.hash
|
220
|
+
else
|
221
|
+
logger.warn("[#{addr}] peer sent unknown inv type: #{i.identifier}")
|
221
222
|
end
|
222
223
|
end
|
223
224
|
logger.info("receive block= #{blocks.size}, txs: #{txs.size}")
|