tapyrus 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +2 -2
  3. data/.ruby-version +1 -1
  4. data/README.md +43 -2
  5. data/lib/tapyrus/ext_key.rb +8 -4
  6. data/lib/tapyrus/key.rb +1 -1
  7. data/lib/tapyrus/key_path.rb +17 -13
  8. data/lib/tapyrus/message/fee_filter.rb +2 -2
  9. data/lib/tapyrus/message/header_and_short_ids.rb +4 -4
  10. data/lib/tapyrus/message/inventory.rb +1 -1
  11. data/lib/tapyrus/message/network_addr.rb +2 -2
  12. data/lib/tapyrus/message/ping.rb +2 -2
  13. data/lib/tapyrus/message/pong.rb +2 -2
  14. data/lib/tapyrus/message/send_cmpct.rb +2 -2
  15. data/lib/tapyrus/message/version.rb +3 -3
  16. data/lib/tapyrus/mnemonic.rb +9 -4
  17. data/lib/tapyrus/pstt/input.rb +422 -0
  18. data/lib/tapyrus/pstt/key_origin_info.rb +63 -0
  19. data/lib/tapyrus/pstt/output.rb +129 -0
  20. data/lib/tapyrus/pstt/proprietary.rb +54 -0
  21. data/lib/tapyrus/pstt/tx.rb +658 -0
  22. data/lib/tapyrus/pstt.rb +335 -0
  23. data/lib/tapyrus/rpc.rb +0 -2
  24. data/lib/tapyrus/script/script.rb +14 -4
  25. data/lib/tapyrus/secp256k1/rfc6979.rb +6 -3
  26. data/lib/tapyrus/tip0020.rb +341 -0
  27. data/lib/tapyrus/tx.rb +6 -2
  28. data/lib/tapyrus/tx_out.rb +2 -2
  29. data/lib/tapyrus/util.rb +3 -3
  30. data/lib/tapyrus/version.rb +1 -1
  31. data/lib/tapyrus/wallet/account.rb +2 -2
  32. data/lib/tapyrus/wallet/db.rb +3 -3
  33. data/lib/tapyrus/wallet/master_key.rb +2 -2
  34. data/lib/tapyrus.rb +3 -3
  35. data/tapyrusrb.gemspec +0 -4
  36. metadata +10 -81
  37. data/exe/tapyrusrb-cli +0 -5
  38. data/exe/tapyrusrbd +0 -42
  39. data/lib/tapyrus/network/connection.rb +0 -70
  40. data/lib/tapyrus/network/message_handler.rb +0 -244
  41. data/lib/tapyrus/network/peer.rb +0 -210
  42. data/lib/tapyrus/network/peer_discovery.rb +0 -43
  43. data/lib/tapyrus/network/pool.rb +0 -135
  44. data/lib/tapyrus/network.rb +0 -11
  45. data/lib/tapyrus/node/cli.rb +0 -114
  46. data/lib/tapyrus/node/configuration.rb +0 -36
  47. data/lib/tapyrus/node/spv.rb +0 -78
  48. data/lib/tapyrus/node.rb +0 -7
  49. data/lib/tapyrus/rpc/http_server.rb +0 -64
  50. data/lib/tapyrus/rpc/request_handler.rb +0 -146
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapyrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ecdsa
@@ -23,20 +23,6 @@ dependencies:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0'
26
- - !ruby/object:Gem::Dependency
27
- name: eventmachine
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
26
  - !ruby/object:Gem::Dependency
41
27
  name: murmurhash3
42
28
  requirement: !ruby/object:Gem::Requirement
@@ -65,20 +51,6 @@ dependencies:
65
51
  - - ">="
66
52
  - !ruby/object:Gem::Version
67
53
  version: '0'
68
- - !ruby/object:Gem::Dependency
69
- name: thor
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
- type: :runtime
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: '0'
82
54
  - !ruby/object:Gem::Dependency
83
55
  name: ffi
84
56
  requirement: !ruby/object:Gem::Requirement
@@ -107,20 +79,6 @@ dependencies:
107
79
  - - "~>"
108
80
  - !ruby/object:Gem::Version
109
81
  version: 1.0.0
110
- - !ruby/object:Gem::Dependency
111
- name: eventmachine_httpserver
112
- requirement: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- type: :runtime
118
- prerelease: false
119
- version_requirements: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: '0'
124
82
  - !ruby/object:Gem::Dependency
125
83
  name: iniparse
126
84
  requirement: !ruby/object:Gem::Requirement
@@ -163,26 +121,6 @@ dependencies:
163
121
  - - ">="
164
122
  - !ruby/object:Gem::Version
165
123
  version: 5.2.3
166
- - !ruby/object:Gem::Dependency
167
- name: json_pure
168
- requirement: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - ">="
171
- - !ruby/object:Gem::Version
172
- version: 2.6.3
173
- - - "<"
174
- - !ruby/object:Gem::Version
175
- version: 2.8.0
176
- type: :runtime
177
- prerelease: false
178
- version_requirements: !ruby/object:Gem::Requirement
179
- requirements:
180
- - - ">="
181
- - !ruby/object:Gem::Version
182
- version: 2.6.3
183
- - - "<"
184
- - !ruby/object:Gem::Version
185
- version: 2.8.0
186
124
  - !ruby/object:Gem::Dependency
187
125
  name: terminal-table
188
126
  requirement: !ruby/object:Gem::Requirement
@@ -328,8 +266,6 @@ email:
328
266
  - azuchi@chaintope.com
329
267
  executables:
330
268
  - tapyrus-script-debugger
331
- - tapyrusrb-cli
332
- - tapyrusrbd
333
269
  extensions: []
334
270
  extra_rdoc_files: []
335
271
  files:
@@ -348,8 +284,6 @@ files:
348
284
  - bin/console
349
285
  - bin/setup
350
286
  - exe/tapyrus-script-debugger
351
- - exe/tapyrusrb-cli
352
- - exe/tapyrusrbd
353
287
  - lib/openassets.rb
354
288
  - lib/openassets/marker_output.rb
355
289
  - lib/openassets/payload.rb
@@ -421,21 +355,15 @@ files:
421
355
  - lib/tapyrus/mnemonic/wordlist/italian.txt
422
356
  - lib/tapyrus/mnemonic/wordlist/japanese.txt
423
357
  - lib/tapyrus/mnemonic/wordlist/spanish.txt
424
- - lib/tapyrus/network.rb
425
- - lib/tapyrus/network/connection.rb
426
- - lib/tapyrus/network/message_handler.rb
427
- - lib/tapyrus/network/peer.rb
428
- - lib/tapyrus/network/peer_discovery.rb
429
- - lib/tapyrus/network/pool.rb
430
- - lib/tapyrus/node.rb
431
- - lib/tapyrus/node/cli.rb
432
- - lib/tapyrus/node/configuration.rb
433
- - lib/tapyrus/node/spv.rb
434
358
  - lib/tapyrus/opcodes.rb
435
359
  - lib/tapyrus/out_point.rb
360
+ - lib/tapyrus/pstt.rb
361
+ - lib/tapyrus/pstt/input.rb
362
+ - lib/tapyrus/pstt/key_origin_info.rb
363
+ - lib/tapyrus/pstt/output.rb
364
+ - lib/tapyrus/pstt/proprietary.rb
365
+ - lib/tapyrus/pstt/tx.rb
436
366
  - lib/tapyrus/rpc.rb
437
- - lib/tapyrus/rpc/http_server.rb
438
- - lib/tapyrus/rpc/request_handler.rb
439
367
  - lib/tapyrus/rpc/tapyrus_core_client.rb
440
368
  - lib/tapyrus/script/color.rb
441
369
  - lib/tapyrus/script/debugger.rb
@@ -457,6 +385,7 @@ files:
457
385
  - lib/tapyrus/store/db.rb
458
386
  - lib/tapyrus/store/db/level_db.rb
459
387
  - lib/tapyrus/store/spv_chain.rb
388
+ - lib/tapyrus/tip0020.rb
460
389
  - lib/tapyrus/tip0137.rb
461
390
  - lib/tapyrus/tx.rb
462
391
  - lib/tapyrus/tx_builder.rb
@@ -490,7 +419,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
490
419
  - !ruby/object:Gem::Version
491
420
  version: '0'
492
421
  requirements: []
493
- rubygems_version: 3.6.3
422
+ rubygems_version: 4.0.3
494
423
  specification_version: 4
495
424
  summary: The implementation of Tapyrus Protocol for Ruby.
496
425
  test_files: []
data/exe/tapyrusrb-cli DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "tapyrus"
4
-
5
- Tapyrus::Node::CLI.start(ARGV)
data/exe/tapyrusrbd DELETED
@@ -1,42 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require "thor"
3
- require "tapyrus"
4
- require "daemon_spawn"
5
-
6
- class TapyrusDaemon < DaemonSpawn::Base
7
- def start(args)
8
- puts "Tapyrusrb daemon start : #{Time.now}"
9
- conf = Tapyrus::Node::Configuration.new(network: args.first[:network])
10
- node = Tapyrus::Node::SPV.new(conf)
11
- node.run
12
- end
13
- end
14
-
15
- class Tapyrusrbd < Thor
16
- class_option :network, aliases: "-n", default: :prod
17
-
18
- desc "start", "start tapyrusrb daemon."
19
- def start
20
- network = options["network"] ? options["network"].to_sym : :prod
21
- Tapyrus.chain_params = network
22
- FileUtils.mkdir_p(Tapyrus.base_dir)
23
- execute_daemon(["start", network: network])
24
- end
25
-
26
- private
27
-
28
- def execute_daemon(cmd_args)
29
- TapyrusDaemon.spawn!(
30
- {
31
- working_dir: Tapyrus.base_dir,
32
- log_file: "#{Tapyrus.base_dir}/log/tapyrusrbd.log",
33
- pid_file: "#{Tapyrus.base_dir}/tapyrusrbd.pid",
34
- sync_log: true,
35
- singleton: true
36
- },
37
- cmd_args
38
- )
39
- end
40
- end
41
-
42
- Tapyrusrbd.start(ARGV)
@@ -1,70 +0,0 @@
1
- module Tapyrus
2
- module Network
3
- # Basic Bitcoin P2P connection class
4
- class Connection < EM::Connection
5
- include MessageHandler
6
-
7
- attr_reader :peer, :logger
8
-
9
- # remote peer version.
10
- attr_accessor :version
11
-
12
- # if true, this peer send new block announcements using a headers message rather than an inv message.
13
- attr_accessor :sendheaders
14
-
15
- # minimum fee(in satoshis per kilobyte) for relay tx
16
- attr_accessor :fee_rate
17
-
18
- def initialize(peer)
19
- @peer = peer
20
- @logger = peer.logger
21
- @sendheaders = false
22
- @attr_accessor = 0
23
- @message = ""
24
- self.pending_connect_timeout = 5.0
25
- end
26
-
27
- def post_init
28
- logger.info "connected. #{addr}"
29
- peer.conn_time = Time.now.to_i
30
- begin_handshake
31
- end
32
-
33
- # handle receiving data from remote node.
34
- def receive_data(data)
35
- handle(data)
36
- end
37
-
38
- def post_handshake
39
- peer.post_handshake
40
- end
41
-
42
- def addr
43
- peer.addr
44
- end
45
-
46
- # close network connection.
47
- def close(msg = "")
48
- logger.info "close connection with #{addr}. #{msg}"
49
- close_connection_after_writing
50
- end
51
-
52
- def handle_error(e)
53
- peer.handle_error(e)
54
- end
55
-
56
- def unbind
57
- logger.info "unbind. #{addr}"
58
- peer.unbind
59
- end
60
-
61
- private
62
-
63
- # start handshake
64
- def begin_handshake
65
- logger.info "begin handshake with #{addr}"
66
- send_message(peer.local_version)
67
- end
68
- end
69
- end
70
- end
@@ -1,244 +0,0 @@
1
- module Tapyrus
2
- module Network
3
- # P2P message handler used by peer connection class.
4
- module MessageHandler
5
- using Tapyrus::Ext
6
-
7
- # handle p2p message.
8
- def handle(message)
9
- peer.last_recv = Time.now.to_i
10
- peer.bytes_recv += message.bytesize
11
- begin
12
- parse(message)
13
- rescue Tapyrus::Message::Error => e
14
- logger.error("invalid header magic. #{e.message}")
15
- close
16
- end
17
- end
18
-
19
- def parse(message)
20
- @message += message
21
- command, payload, rest = parse_header
22
- return unless command
23
-
24
- defer_handle_command(command, payload)
25
- @message = ""
26
- parse(rest) if rest && rest.bytesize > 0
27
- end
28
-
29
- def parse_header
30
- head_magic = Tapyrus.chain_params.magic_head
31
- return if @message.nil? || @message.size < MESSAGE_HEADER_SIZE
32
-
33
- magic, command, length, checksum = @message.unpack("a4A12Va4")
34
- raise Tapyrus::Message::Error, "invalid header magic. #{magic.bth}" unless magic.bth == head_magic
35
-
36
- payload = @message[MESSAGE_HEADER_SIZE...(MESSAGE_HEADER_SIZE + length)]
37
- return if payload.size < length
38
- unless Tapyrus.double_sha256(payload)[0...4] == checksum
39
- raise Tapyrus::Message::Error, "header checksum mismatch. #{checksum.bth}"
40
- end
41
-
42
- rest = @message[(MESSAGE_HEADER_SIZE + length)..-1]
43
- [command, payload, rest]
44
- end
45
-
46
- # handle command with EM#defer
47
- def defer_handle_command(command, payload)
48
- operation = proc { handle_command(command, payload) }
49
- callback = proc { |result| }
50
- errback =
51
- proc do |e|
52
- logger.error("error occurred. #{e.message}")
53
- logger.error(e.backtrace)
54
- peer.handle_error(e)
55
- end
56
- EM.defer(operation, callback, errback)
57
- end
58
-
59
- def handle_command(command, payload)
60
- logger.info("[#{addr}] process command #{command}.")
61
- case command
62
- when Tapyrus::Message::Version::COMMAND
63
- on_version(Tapyrus::Message::Version.parse_from_payload(payload))
64
- when Tapyrus::Message::VerAck::COMMAND
65
- on_ver_ack
66
- when Tapyrus::Message::GetAddr::COMMAND
67
- on_get_addr
68
- when Tapyrus::Message::Addr::COMMAND
69
- on_addr(Tapyrus::Message::Addr.parse_from_payload(payload))
70
- when Tapyrus::Message::SendHeaders::COMMAND
71
- on_send_headers
72
- when Tapyrus::Message::FeeFilter::COMMAND
73
- on_fee_filter(Tapyrus::Message::FeeFilter.parse_from_payload(payload))
74
- when Tapyrus::Message::Ping::COMMAND
75
- on_ping(Tapyrus::Message::Ping.parse_from_payload(payload))
76
- when Tapyrus::Message::Pong::COMMAND
77
- on_pong(Tapyrus::Message::Pong.parse_from_payload(payload))
78
- when Tapyrus::Message::GetHeaders::COMMAND
79
- on_get_headers(Tapyrus::Message::GetHeaders.parse_from_payload(payload))
80
- when Tapyrus::Message::Headers::COMMAND
81
- on_headers(Tapyrus::Message::Headers.parse_from_payload(payload))
82
- when Tapyrus::Message::Block::COMMAND
83
- on_block(Tapyrus::Message::Block.parse_from_payload(payload))
84
- when Tapyrus::Message::Tx::COMMAND
85
- on_tx(Tapyrus::Message::Tx.parse_from_payload(payload))
86
- when Tapyrus::Message::NotFound::COMMAND
87
- on_not_found(Tapyrus::Message::NotFound.parse_from_payload(payload))
88
- when Tapyrus::Message::MemPool::COMMAND
89
- on_mem_pool
90
- when Tapyrus::Message::Reject::COMMAND
91
- on_reject(Tapyrus::Message::Reject.parse_from_payload(payload))
92
- when Tapyrus::Message::SendCmpct::COMMAND
93
- on_send_cmpct(Tapyrus::Message::SendCmpct.parse_from_payload(payload))
94
- when Tapyrus::Message::Inv::COMMAND
95
- on_inv(Tapyrus::Message::Inv.parse_from_payload(payload))
96
- when Tapyrus::Message::MerkleBlock::COMMAND
97
- on_merkle_block(Tapyrus::Message::MerkleBlock.parse_from_payload(payload))
98
- when Tapyrus::Message::CmpctBlock::COMMAND
99
- on_cmpct_block(Tapyrus::Message::CmpctBlock.parse_from_payload(payload))
100
- when Tapyrus::Message::GetData::COMMAND
101
- on_get_data(Tapyrus::Message::GetData.parse_from_payload(payload))
102
- else
103
- logger.warn("unsupported command received. command: #{command}, payload: #{payload.bth}")
104
- close("with command #{command}")
105
- end
106
- end
107
-
108
- def send_message(msg)
109
- logger.info "send message #{msg.class::COMMAND}"
110
- pkt = msg.to_pkt
111
- peer.last_send = Time.now.to_i
112
- peer.bytes_sent = pkt.bytesize
113
- send_data(pkt)
114
- end
115
-
116
- def handshake_done
117
- return unless @incomming_handshake && @outgoing_handshake
118
- logger.info "handshake finished."
119
- @connected = true
120
- post_handshake
121
- end
122
-
123
- def on_version(version)
124
- logger.info("receive version message. #{version.build_json}")
125
- @version = version
126
- send_message(Tapyrus::Message::VerAck.new)
127
- @incomming_handshake = true
128
- handshake_done
129
- end
130
-
131
- def on_ver_ack
132
- logger.info("receive verack message.")
133
- @outgoing_handshake = true
134
- handshake_done
135
- end
136
-
137
- def on_get_addr
138
- logger.info("receive getaddr message.")
139
- peer.send_addrs
140
- end
141
-
142
- def on_addr(addr)
143
- logger.info("receive addr message. #{addr.build_json}")
144
- # TODO
145
- end
146
-
147
- def on_send_headers
148
- logger.info("receive sendheaders message.")
149
- @sendheaders = true
150
- end
151
-
152
- def on_fee_filter(fee_filter)
153
- logger.info("receive feefilter message. #{fee_filter.build_json}")
154
- @fee_rate = fee_filter.fee_rate
155
- end
156
-
157
- def on_ping(ping)
158
- logger.info("receive ping message. #{ping.build_json}")
159
- send_message(ping.to_response)
160
- end
161
-
162
- def on_pong(pong)
163
- logger.info("receive pong message. #{pong.build_json}")
164
- if pong.nonce == peer.last_ping_nonce
165
- peer.last_ping_nonce = nil
166
- peer.last_pong = Time.now.to_i
167
- else
168
- logger.debug "The remote peer sent the wrong nonce (#{pong.nonce})."
169
- end
170
- end
171
-
172
- def on_get_headers(headers)
173
- logger.info("receive getheaders message.")
174
- # TODO
175
- end
176
-
177
- def on_headers(headers)
178
- logger.info("receive headers message.")
179
- peer.handle_headers(headers)
180
- end
181
-
182
- def on_block(block)
183
- logger.info("receive block message.")
184
- # TODO
185
- end
186
-
187
- def on_tx(tx)
188
- logger.info("receive tx message. #{tx.build_json}")
189
- peer.handle_tx(tx)
190
- end
191
-
192
- def on_not_found(not_found)
193
- logger.info("receive notfound message. #{not_found.build_json}")
194
- # TODO
195
- end
196
-
197
- def on_mem_pool
198
- logger.info("receive mempool message.")
199
- # TODO return mempool tx
200
- end
201
-
202
- def on_reject(reject)
203
- logger.warn("receive reject message. #{reject.build_json}")
204
- # TODO
205
- end
206
-
207
- def on_send_cmpct(cmpct)
208
- logger.info("receive sendcmpct message. #{cmpct.build_json}")
209
- # TODO if mode is high and version is 1, relay block with cmpctblock message
210
- end
211
-
212
- def on_inv(inv)
213
- logger.info("receive inv message.")
214
- blocks = []
215
- txs = []
216
- inv.inventories.each do |i|
217
- case i.identifier
218
- when Tapyrus::Message::Inventory::MSG_TX
219
- txs << i.hash
220
- when Tapyrus::Message::Inventory::MSG_BLOCK
221
- blocks << i.hash
222
- else
223
- logger.warn("[#{addr}] peer sent unknown inv type: #{i.identifier}")
224
- end
225
- end
226
- logger.info("receive block= #{blocks.size}, txs: #{txs.size}")
227
- peer.handle_block_inv(blocks) unless blocks.empty?
228
- end
229
-
230
- def on_merkle_block(merkle_block)
231
- logger.info("receive merkle block message. #{merkle_block.build_json}")
232
- peer.handle_merkle_block(merkle_block)
233
- end
234
-
235
- def on_cmpct_block(cmpct_block)
236
- logger.info("receive cmpct_block message. #{cmpct_block.build_json}")
237
- end
238
-
239
- def on_get_data(get_data)
240
- logger.info("receive get data message. #{get_data.build_json}")
241
- end
242
- end
243
- end
244
- end