tapyrus 0.2.7 → 0.2.8
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 +2 -3
- data/lib/schnorr/signature.rb +3 -6
- data/lib/tapyrus.rb +6 -22
- data/lib/tapyrus/base58.rb +7 -6
- 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 +38 -34
- 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/http_server.rb +21 -22
- data/lib/tapyrus/rpc/request_handler.rb +42 -44
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +53 -25
- data/lib/tapyrus/script/color.rb +10 -0
- data/lib/tapyrus/script/multisig.rb +13 -12
- data/lib/tapyrus/script/script.rb +72 -71
- 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 +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/tapyrusrb.gemspec +13 -14
- metadata +21 -4
- data/.travis.yml +0 -14
data/lib/tapyrus/network/peer.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Network
|
3
|
-
|
4
3
|
# remote peer class.
|
5
4
|
class Peer
|
6
|
-
|
7
5
|
# Interval for pinging peers.
|
8
6
|
PING_INTERVAL = 2 * 60
|
9
7
|
|
@@ -22,13 +20,16 @@ module Tapyrus
|
|
22
20
|
attr_accessor :outbound # TODO need implements to accept inbound connection
|
23
21
|
attr_accessor :best_hash
|
24
22
|
attr_accessor :best_height
|
23
|
+
|
25
24
|
# remote peer info
|
26
25
|
attr_reader :host
|
27
26
|
attr_reader :port
|
27
|
+
|
28
28
|
# remote peer connection
|
29
29
|
attr_accessor :conn
|
30
30
|
attr_accessor :connected
|
31
31
|
attr_accessor :primary
|
32
|
+
|
32
33
|
# parent pool
|
33
34
|
attr_reader :pool
|
34
35
|
attr_reader :chain
|
@@ -51,7 +52,8 @@ module Tapyrus
|
|
51
52
|
@relay = configuration.conf[:relay]
|
52
53
|
current_height = @chain.latest_block.height
|
53
54
|
remote_addr = Tapyrus::Message::NetworkAddr.new(ip: host, port: port, time: nil)
|
54
|
-
@local_version =
|
55
|
+
@local_version =
|
56
|
+
Tapyrus::Message::Version.new(remote_addr: remote_addr, start_height: current_height, relay: @relay)
|
55
57
|
end
|
56
58
|
|
57
59
|
def connect
|
@@ -84,16 +86,17 @@ module Tapyrus
|
|
84
86
|
def post_handshake
|
85
87
|
@connected = true
|
86
88
|
pool.handle_new_peer(self)
|
89
|
+
|
87
90
|
# require remote peer to use headers message instead fo inv message.
|
88
91
|
conn.send_message(Tapyrus::Message::SendHeaders.new)
|
89
|
-
EM.add_periodic_timer(PING_INTERVAL) {send_ping}
|
92
|
+
EM.add_periodic_timer(PING_INTERVAL) { send_ping }
|
90
93
|
end
|
91
94
|
|
92
95
|
# start block header download
|
93
96
|
def start_block_header_download
|
94
97
|
logger.info("[#{addr}] start block header download.")
|
95
|
-
get_headers =
|
96
|
-
|
98
|
+
get_headers =
|
99
|
+
Tapyrus::Message::GetHeaders.new(Tapyrus.chain_params.protocol_version, [chain.latest_block.block_hash])
|
97
100
|
conn.send_message(get_headers)
|
98
101
|
end
|
99
102
|
|
@@ -129,7 +132,7 @@ module Tapyrus
|
|
129
132
|
@best_height = entry.height
|
130
133
|
end
|
131
134
|
pool.changed
|
132
|
-
pool.notify_observers(:header, {hash: @best_hash, height: @best_height})
|
135
|
+
pool.notify_observers(:header, { hash: @best_hash, height: @best_height })
|
133
136
|
start_block_header_download if headers.headers.size > 0 # next header download
|
134
137
|
end
|
135
138
|
|
@@ -156,14 +159,13 @@ module Tapyrus
|
|
156
159
|
|
157
160
|
# send +addr+ message to remote peer
|
158
161
|
def send_addrs
|
159
|
-
addrs = pool.peers.select{|p|p != self}.map(&:to_network_addr)
|
162
|
+
addrs = pool.peers.select { |p| p != self }.map(&:to_network_addr)
|
160
163
|
conn.send_message(Tapyrus::Message::Addr.new(addrs))
|
161
164
|
end
|
162
165
|
|
163
166
|
# handle block inv message.
|
164
167
|
def handle_block_inv(hashes)
|
165
|
-
getdata = Tapyrus::Message::GetData.new(
|
166
|
-
hashes.map{|h|Tapyrus::Message::Inventory.new(block_type, h)})
|
168
|
+
getdata = Tapyrus::Message::GetData.new(hashes.map { |h| Tapyrus::Message::Inventory.new(block_type, h) })
|
167
169
|
conn.send_message(getdata)
|
168
170
|
end
|
169
171
|
|
@@ -188,8 +190,7 @@ module Tapyrus
|
|
188
190
|
|
189
191
|
# send filterload message.
|
190
192
|
def send_filter_load(bloom)
|
191
|
-
filter_load = Tapyrus::Message::FilterLoad.new(
|
192
|
-
bloom, Tapyrus::Message::FilterLoad::BLOOM_UPDATE_ALL)
|
193
|
+
filter_load = Tapyrus::Message::FilterLoad.new(bloom, Tapyrus::Message::FilterLoad::BLOOM_UPDATE_ALL)
|
193
194
|
conn.send_message(filter_load)
|
194
195
|
end
|
195
196
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Network
|
3
|
-
|
4
3
|
class PeerDiscovery
|
5
|
-
|
6
4
|
attr_reader :logger, :configuration
|
7
5
|
|
8
6
|
def initialize(configuration)
|
@@ -28,14 +26,14 @@ module Tapyrus
|
|
28
26
|
|
29
27
|
def find_from_dns_seeds
|
30
28
|
logger.debug 'discover peer address from DNS seeds.'
|
31
|
-
dns_seeds.map
|
29
|
+
dns_seeds.map do |seed|
|
32
30
|
begin
|
33
|
-
Socket.getaddrinfo(seed, Tapyrus.chain_params.default_port).map{|a|a[2]}.uniq
|
31
|
+
Socket.getaddrinfo(seed, Tapyrus.chain_params.default_port).map { |a| a[2] }.uniq
|
34
32
|
rescue SocketError => e
|
35
33
|
logger.error "SocketError occurred when load DNS seed: #{seed}, error: #{e.message}"
|
36
34
|
nil
|
37
35
|
end
|
38
|
-
|
36
|
+
end.flatten.compact
|
39
37
|
end
|
40
38
|
end
|
41
39
|
end
|
data/lib/tapyrus/network/pool.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module Tapyrus
|
2
|
-
|
3
2
|
module Network
|
4
|
-
|
5
3
|
# Time between pings automatically sent out for latency probing and keepalive (in seconds).
|
6
4
|
PING_INTERVAL = 2 * 60
|
5
|
+
|
7
6
|
# Time after which to disconnect, after waiting for a ping response (or inactivity).
|
8
7
|
TIMEOUT_INTERVAL = 20 * 60
|
8
|
+
|
9
9
|
# Maximum number of automatic outgoing nodes
|
10
10
|
MAX_OUTBOUND_CONNECTIONS = 4
|
11
11
|
|
@@ -112,23 +112,23 @@ module Tapyrus
|
|
112
112
|
# allocate new peer id
|
113
113
|
def allocate_peer_id
|
114
114
|
id = 0
|
115
|
-
until peers.empty? || peers.find{|p|p.id == id}.nil?
|
116
|
-
id += 1
|
117
|
-
end
|
115
|
+
id += 1 until peers.empty? || peers.find { |p| p.id == id }.nil?
|
118
116
|
id
|
119
117
|
end
|
120
118
|
|
121
119
|
def connect(addr_list)
|
122
120
|
port = Tapyrus.chain_params.default_port
|
123
121
|
|
124
|
-
EM::Iterator
|
125
|
-
|
126
|
-
|
127
|
-
pending_peers
|
128
|
-
|
129
|
-
|
122
|
+
EM::Iterator
|
123
|
+
.new(addr_list, Tapyrus::PARALLEL_THREAD)
|
124
|
+
.each do |ip, iter|
|
125
|
+
if pending_peers.size + peers.size < MAX_OUTBOUND_CONNECTIONS
|
126
|
+
peer = Peer.new(ip, port, self, @configuration)
|
127
|
+
pending_peers << peer
|
128
|
+
peer.connect
|
129
|
+
iter.next
|
130
|
+
end
|
130
131
|
end
|
131
|
-
end
|
132
132
|
end
|
133
133
|
end
|
134
134
|
end
|
data/lib/tapyrus/node.rb
CHANGED
data/lib/tapyrus/node/cli.rb
CHANGED
@@ -4,9 +4,7 @@ require 'json'
|
|
4
4
|
|
5
5
|
module Tapyrus
|
6
6
|
module Node
|
7
|
-
|
8
7
|
class CLI < Thor
|
9
|
-
|
10
8
|
class_option :network, aliases: '-n', default: :prod
|
11
9
|
|
12
10
|
desc 'getblockchaininfo', 'Returns an object containing various state info regarding blockchain processing.'
|
@@ -19,7 +17,8 @@ module Tapyrus
|
|
19
17
|
request('stop')
|
20
18
|
end
|
21
19
|
|
22
|
-
desc 'getblockheader "hash" ( verbose )',
|
20
|
+
desc 'getblockheader "hash" ( verbose )',
|
21
|
+
'If verbose is false, returns a string that is serialized, hex-encoded data for blockheader "hash". If verbose is true, returns an Object with information about blockheader <hash>.'
|
23
22
|
def getblockheader(hash, verbose = true)
|
24
23
|
verbose = verbose.is_a?(String) ? (verbose == 'true') : verbose
|
25
24
|
request('getblockheader', hash, verbose)
|
@@ -30,7 +29,8 @@ module Tapyrus
|
|
30
29
|
request('getpeerinfo')
|
31
30
|
end
|
32
31
|
|
33
|
-
desc 'decoderawtransaction "hexstring"',
|
32
|
+
desc 'decoderawtransaction "hexstring"',
|
33
|
+
'Return a JSON object representing the serialized, hex-encoded transaction.'
|
34
34
|
def decoderawtransaction(hexstring)
|
35
35
|
request('decoderawtransaction', hexstring)
|
36
36
|
end
|
@@ -47,12 +47,14 @@ module Tapyrus
|
|
47
47
|
request('sendrawtransaction', hex_tx)
|
48
48
|
end
|
49
49
|
|
50
|
-
desc 'createwallet "wallet_id"',
|
50
|
+
desc 'createwallet "wallet_id"',
|
51
|
+
'Create new HD wallet. It returns an error if an existing wallet_id is specified. '
|
51
52
|
def createwallet(wallet_id)
|
52
53
|
request('createwallet', wallet_id)
|
53
54
|
end
|
54
55
|
|
55
|
-
desc 'listwallets',
|
56
|
+
desc 'listwallets',
|
57
|
+
'Returns a list of currently loaded wallets. For full information on the wallet, use "getwalletinfo"'
|
56
58
|
def listwallets
|
57
59
|
request('listwallets')
|
58
60
|
end
|
@@ -67,7 +69,8 @@ module Tapyrus
|
|
67
69
|
request('listaccounts')
|
68
70
|
end
|
69
71
|
|
70
|
-
desc 'encryptwallet "passphrase"',
|
72
|
+
desc 'encryptwallet "passphrase"',
|
73
|
+
'Encrypts the wallet with "passphrase". This is for first time encryption.After this, any calls that interact with private keys such as sending or signing will require the passphrase to be set prior the making these calls.'
|
71
74
|
def encryptwallet(passhphrase)
|
72
75
|
request('encryptwallet', passhphrase)
|
73
76
|
end
|
@@ -86,15 +89,11 @@ module Tapyrus
|
|
86
89
|
end
|
87
90
|
|
88
91
|
def request(command, *params)
|
89
|
-
data = {
|
90
|
-
:method => command,
|
91
|
-
:params => params,
|
92
|
-
:id => 'jsonrpc'
|
93
|
-
}
|
92
|
+
data = { method: command, params: params, id: 'jsonrpc' }
|
94
93
|
begin
|
95
94
|
uri = URI.parse(config.server_url)
|
96
95
|
http = Net::HTTP.new(uri.hostname, uri.port)
|
97
|
-
http.use_ssl = uri.scheme ===
|
96
|
+
http.use_ssl = uri.scheme === 'https'
|
98
97
|
request = Net::HTTP::Post.new('/')
|
99
98
|
request.content_type = 'application/json'
|
100
99
|
request.body = data.to_json
|
@@ -110,7 +109,6 @@ module Tapyrus
|
|
110
109
|
puts e.message
|
111
110
|
end
|
112
111
|
end
|
113
|
-
|
114
112
|
end
|
115
113
|
end
|
116
114
|
end
|
@@ -3,7 +3,6 @@ require 'iniparse'
|
|
3
3
|
module Tapyrus
|
4
4
|
module Node
|
5
5
|
class Configuration
|
6
|
-
|
7
6
|
attr_reader :conf
|
8
7
|
|
9
8
|
def initialize(opts = {})
|
@@ -14,7 +13,7 @@ module Tapyrus
|
|
14
13
|
|
15
14
|
begin
|
16
15
|
ini_file = IniParse.parse(File.read("#{Tapyrus.base_dir}/tapyrusrb.conf"))
|
17
|
-
@conf = Hash[
|
16
|
+
@conf = Hash[ini_file.to_h['__anonymous__'].map { |k, v| [k.to_sym, v] }]
|
18
17
|
rescue => e
|
19
18
|
@conf = {}
|
20
19
|
end
|
@@ -32,7 +31,6 @@ module Tapyrus
|
|
32
31
|
def server_url
|
33
32
|
"http://#{host}:#{port}"
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/lib/tapyrus/node/spv.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Node
|
3
|
-
|
4
3
|
# SPV class
|
5
4
|
class SPV
|
6
|
-
|
7
5
|
attr_reader :chain
|
8
6
|
attr_reader :pool
|
9
7
|
attr_reader :logger
|
@@ -20,6 +18,7 @@ module Tapyrus
|
|
20
18
|
@logger = Tapyrus::Logger.create(:debug)
|
21
19
|
@running = false
|
22
20
|
@wallet = Tapyrus::Wallet::Base.current_wallet
|
21
|
+
|
23
22
|
# TODO : optimize bloom filter parameters
|
24
23
|
setup_filter
|
25
24
|
end
|
@@ -72,7 +71,7 @@ module Tapyrus
|
|
72
71
|
|
73
72
|
def setup_filter
|
74
73
|
@bloom = Tapyrus::BloomFilter.create_filter(512, 0.01)
|
75
|
-
wallet.watch_targets.each{|t|bloom.add(t.htb)} if wallet
|
74
|
+
wallet.watch_targets.each { |t| bloom.add(t.htb) } if wallet
|
76
75
|
end
|
77
76
|
end
|
78
77
|
end
|
data/lib/tapyrus/opcodes.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Tapyrus
|
2
|
-
|
3
2
|
# https://bitcoin.org/en/developer-reference#opcodes
|
4
3
|
module Opcodes
|
5
|
-
|
6
4
|
module_function
|
7
5
|
|
8
6
|
# https://en.bitcoin.it/wiki/Script#Constants
|
@@ -111,7 +109,7 @@ module Tapyrus
|
|
111
109
|
OP_HASH256 = 0xaa
|
112
110
|
OP_CODESEPARATOR = 0xab
|
113
111
|
OP_CHECKSIG = 0xac
|
114
|
-
OP_CHECKSIGVERIFY= 0xad
|
112
|
+
OP_CHECKSIGVERIFY = 0xad
|
115
113
|
OP_CHECKMULTISIG = 0xae
|
116
114
|
OP_CHECKMULTISIGVERIFY = 0xaf
|
117
115
|
|
@@ -124,7 +122,7 @@ module Tapyrus
|
|
124
122
|
OP_VER = 0x62
|
125
123
|
OP_VERIF = 0x65
|
126
124
|
OP_VERNOTIF = 0x66
|
127
|
-
OP_RESERVED1= 0x89
|
125
|
+
OP_RESERVED1 = 0x89
|
128
126
|
OP_RESERVED2 = 0x8a
|
129
127
|
|
130
128
|
OP_NOP1 = 0xb0
|
@@ -147,7 +145,12 @@ module Tapyrus
|
|
147
145
|
OP_COLOR = 0xbc
|
148
146
|
|
149
147
|
DUPLICATE_KEY = [:OP_NOP2, :OP_NOP3]
|
150
|
-
OPCODES_MAP =
|
148
|
+
OPCODES_MAP =
|
149
|
+
Hash[
|
150
|
+
*(constants.grep(/^OP_/) - [:OP_NOP2, :OP_NOP3, :OP_CHECKLOCKTIMEVERIFY, :OP_CHECKSEQUENCEVERIFY]).map do |c|
|
151
|
+
[const_get(c), c.to_s]
|
152
|
+
end.flatten
|
153
|
+
]
|
151
154
|
NAME_MAP = Hash[*constants.grep(/^OP_/).map { |c| [c.to_s, const_get(c)] }.flatten]
|
152
155
|
|
153
156
|
def opcode_to_name(opcode)
|
@@ -178,6 +181,5 @@ module Tapyrus
|
|
178
181
|
return opcode - (OP_1 - 1) if opcode >= OP_1 && opcode <= OP_16
|
179
182
|
nil
|
180
183
|
end
|
181
|
-
|
182
184
|
end
|
183
|
-
end
|
185
|
+
end
|
data/lib/tapyrus/out_point.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
|
-
|
3
2
|
# outpoint class
|
4
3
|
class OutPoint
|
5
|
-
|
6
4
|
COINBASE_HASH = '0000000000000000000000000000000000000000000000000000000000000000'
|
7
|
-
COINBASE_INDEX =
|
5
|
+
COINBASE_INDEX = 4_294_967_295
|
8
6
|
|
9
7
|
attr_reader :tx_hash
|
10
8
|
attr_reader :index
|
@@ -34,11 +32,13 @@ module Tapyrus
|
|
34
32
|
index >= 0 && (!coinbase? && tx_hash != COINBASE_HASH)
|
35
33
|
end
|
36
34
|
|
35
|
+
def ==(other)
|
36
|
+
to_payload == other&.to_payload
|
37
|
+
end
|
38
|
+
|
37
39
|
# convert hash to txid
|
38
40
|
def txid
|
39
41
|
tx_hash.rhex
|
40
42
|
end
|
41
|
-
|
42
43
|
end
|
43
|
-
|
44
44
|
end
|
@@ -3,7 +3,6 @@ require 'json'
|
|
3
3
|
|
4
4
|
module Tapyrus
|
5
5
|
module RPC
|
6
|
-
|
7
6
|
# Tapyrusrb RPC server.
|
8
7
|
class HttpServer < EM::Connection
|
9
8
|
include EM::HttpServer
|
@@ -28,27 +27,29 @@ module Tapyrus
|
|
28
27
|
|
29
28
|
# process http request.
|
30
29
|
def process_http_request
|
31
|
-
operation =
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
e
|
30
|
+
operation =
|
31
|
+
proc do
|
32
|
+
command, args = parse_json_params
|
33
|
+
logger.debug("process http request. command = #{command}")
|
34
|
+
begin
|
35
|
+
send(command, *args).to_json
|
36
|
+
rescue Exception => e
|
37
|
+
e
|
38
|
+
end
|
38
39
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
40
|
+
callback =
|
41
|
+
proc do |result|
|
42
|
+
response = EM::DelegatedHttpResponse.new(self)
|
43
|
+
if result.is_a?(Exception)
|
44
|
+
response.status = 500
|
45
|
+
response.content = result.message
|
46
|
+
else
|
47
|
+
response.status = 200
|
48
|
+
response.content = result
|
49
|
+
end
|
50
|
+
response.content_type 'application/json'
|
51
|
+
response.send_response
|
48
52
|
end
|
49
|
-
response.content_type 'application/json'
|
50
|
-
response.send_response
|
51
|
-
}
|
52
53
|
EM.defer(operation, callback)
|
53
54
|
end
|
54
55
|
|
@@ -58,8 +59,6 @@ module Tapyrus
|
|
58
59
|
params = JSON.parse(@http_post_content)
|
59
60
|
[params['method'], params['params']]
|
60
61
|
end
|
61
|
-
|
62
62
|
end
|
63
|
-
|
64
63
|
end
|
65
64
|
end
|