Class: Bitcoin::Network::CommandHandler
- Inherits:
-
EM::Connection
- Object
- EM::Connection
- Bitcoin::Network::CommandHandler
- Defined in:
- lib/bitcoin/network/command_handler.rb
Overview
Started by the Node, accepts connections from CommandClient and answers requests or registers for events and notifies the clients when they happen.
Instance Method Summary collapse
- #add_monitor(params, channels) ⇒ Object
-
#handle_addrs(params = { count: 32 }) ⇒ Object
Get known peer addresses (used by bin/bitcoin_dns_seed).
-
#handle_assemble_tx(params = {}) ⇒ Object
Assemble an unsigned transaction from the
txandsig_pubkeysparams. -
#handle_config ⇒ Object
Get the currently active configuration.
-
#handle_connect(params) ⇒ Object
Connect to given peer(s).
- #handle_connected ⇒ Object
-
#handle_connections ⇒ Object
Get currently connected peers.
-
#handle_create_tx(params = {}) ⇒ Object
Create a transaction, collecting outputs from given
keys, spending torecipientswith an optionalfee. -
#handle_disconnect(params) ⇒ Object
Disconnect given peer(s).
-
#handle_filter_monitor_output(request) ⇒ Object
Handle filter monitor output command; add given
addressto the list of filtered addresses in the params of the given monitor. -
#handle_getaddr ⇒ Object
Trigger the node to ask its for new peer addresses.
-
#handle_getblocks ⇒ Object
Trigger the node to ask its peers for new blocks.
-
#handle_help ⇒ Object
List all available commands.
-
#handle_info ⇒ Object
Get various statistics.
-
#handle_monitor(request, params) ⇒ Object
Handle
monitorcommand; subscribe client to specified channels (block,tx,output,connection). -
#handle_monitor_block(request, params) ⇒ Object
Handle monitor block command;.
-
#handle_monitor_connection(request, params) ⇒ Object
Handle monitor connection command; send current connections after client is subscribed to :connection channel.
-
#handle_monitor_output(request, params) ⇒ Object
Handle monitor output command.
-
#handle_monitor_reorg(request, params) ⇒ Object
TODO: params (min reorg depth).
-
#handle_monitor_tx(request, params) ⇒ Object
Handle monitor tx command.
-
#handle_relay_tx(request, params = {}) ⇒ Object
Relay given transaction (in hex).
-
#handle_rescan ⇒ Object
Trigger a rescan operation when used with a UtxoStore.
-
#handle_stop ⇒ Object
Stop the bitcoin node.
-
#handle_store_block(params) ⇒ Object
Validate and store given block (in hex) as if it was received by a peer.
-
#handle_store_tx(params) ⇒ Object
Store given transaction (in hex) as if it was received by a peer.
-
#handle_tslb ⇒ Object
Get Time Since Last Block.
-
#handle_unmonitor(request) ⇒ Object
Handle
unmonitorcommand; cancel given subscription. -
#initialize(node) ⇒ CommandHandler
constructor
create new CommandHandler.
-
#log ⇒ Object
wrap logger and append prefix.
-
#receive_data(data) ⇒ Object
receive request from the client.
-
#respond(request, data) ⇒ Object
respond to a command; send serialized response to the client.
- #respond_missed_blocks(request, monitor_id) ⇒ Object
- #respond_missed_outputs(request, monitor_id) ⇒ Object
- #respond_missed_txs(request, params, monitor_id) ⇒ Object
- #respond_monitor_block(request, block, depth = nil) ⇒ Object
- #respond_monitor_output(request, monitor_id, tx, out, idx, conf) ⇒ Object
- #respond_monitor_tx(request, monitor_id, tx, conf = nil) ⇒ Object
-
#unbind ⇒ Object
disconnect notification clients when connection is closed.
Constructor Details
#initialize(node) ⇒ CommandHandler
create new CommandHandler
11 12 13 14 15 16 17 |
# File 'lib/bitcoin/network/command_handler.rb', line 11 def initialize node @node = node @node.command_connections << self @buf = BufferedTokenizer.new("\x00") @lock = Monitor.new @monitors = [] end |
Instance Method Details
#add_monitor(params, channels) ⇒ Object
309 310 311 312 |
# File 'lib/bitcoin/network/command_handler.rb', line 309 def add_monitor params, channels @monitors << { params: params, channels: channels } @monitors.size - 1 end |
#handle_addrs(params = { count: 32 }) ⇒ Object
Get known peer addresses (used by bin/bitcoin_dns_seed).
{ method: "getaddr", params: { count: 32 } }
382 383 384 385 386 387 388 |
# File 'lib/bitcoin/network/command_handler.rb', line 382 def handle_addrs params = { count: 32 } @node.addrs.weighted_sample(params[:count].to_i) do |addr| Time.now.tv_sec + 7200 - addr.time end.map do |addr| [addr.ip, addr.port, Time.now.tv_sec - addr.time] rescue nil end.compact end |
#handle_assemble_tx(params = {}) ⇒ Object
Assemble an unsigned transaction from the tx and sig_pubkeys params. The tx is the regular transaction structure, with empty input scripts (as returned by #create_tx when called without privkeys). sig_pubkeys is an array of [signature, pubkey] pairs used to build the input scripts.
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/bitcoin/network/command_handler.rb', line 455 def handle_assemble_tx params = {} # tx_hex, sig_pubs tx = Bitcoin::P::Tx.new(params[:tx].htb) params[:sig_pubs].each.with_index do |sig_pub, idx| sig, pub = *sig_pub.map(&:htb) script_sig = Bitcoin::Script.to_signature_pubkey_script(sig, pub) tx.in[idx].script_sig_length = script_sig.bytesize tx.in[idx].script_sig = script_sig end tx = Bitcoin::P::Tx.new(tx.to_payload) tx.validator(@node.store).validate(raise_errors: true) { hash: tx.hash, hex: tx.to_payload.hth } rescue { error: "Error assembling tx: #{$!.message}" } p $!; puts *$@ end |
#handle_config ⇒ Object
Get the currently active configuration.
bitcoin_node config
317 318 319 |
# File 'lib/bitcoin/network/command_handler.rb', line 317 def handle_config @node.config end |
#handle_connect(params) ⇒ Object
Connect to given peer(s).
{ method: "connect", params: {host: "localhost", port: 12345 }
343 344 345 346 |
# File 'lib/bitcoin/network/command_handler.rb', line 343 def handle_connect params @node.connect_peer(params[:host], params[:port]) { state: :connecting } end |
#handle_connected ⇒ Object
65 66 67 |
# File 'lib/bitcoin/network/command_handler.rb', line 65 def handle_connected "connected" end |
#handle_connections ⇒ Object
Get currently connected peers.
bitcoin_node connections
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/bitcoin/network/command_handler.rb', line 323 def handle_connections @node.connections.sort{|x,y| y.uptime <=> x.uptime}.map{|c| { type: c.direction, host: c.host, port: c.port, state: c.state, uptime: c.uptime, version: { version: c.version.version, services: c.version.services, time: c.version.time, nonce: c.version.nonce, block: c.version.last_block, client: (c.version.user_agent rescue '?'), relay: c.version.relay, } } } end |
#handle_create_tx(params = {}) ⇒ Object
Create a transaction, collecting outputs from given keys, spending to recipients with an optional fee. Keys is an array that can contain either privkeys, pubkeys or addresses. When a privkey is given, the corresponding inputs are signed. If not, the signature_hash is computed and passed along with the response. After creating an unsigned transaction, one just needs to sign the sig_hashes and send everything to #assemble_tx, to receive the complete transaction that can be relayed to the network.
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'lib/bitcoin/network/command_handler.rb', line 417 def handle_create_tx params = {} params[:fee] ||= 0 #keys, recipients, fee = 0 keystore = Bitcoin::Wallet::SimpleKeyStore.new(file: StringIO.new("[]")) params[:keys].each do |k| begin key = Bitcoin::Key.from_base58(k) key = { addr: key.addr, key: key } rescue if Bitcoin.valid_address?(k) key = { addr: k } else begin key = Bitcoin::Key.new(nil, k) key = { addr: key.addr, key: key } rescue return { error: "Input not valid address, pub- or privkey: #{k}" } end end end keystore.add_key(key) end wallet = Bitcoin::Wallet::Wallet.new(@node.store, keystore) tx = wallet.new_tx(params[:recipients].map {|r| [:address, r[0], r[1]]}, params[:fee]) return { error: "Error creating tx." } unless tx { hash: tx.hash, hex: tx.to_payload.hth, missing_sigs: tx.in.map {|i| [i.sig_hash.hth, i.sig_address] rescue nil } } rescue { error: "Error creating tx: #{$!.message}" } p $!; puts *$@ end |
#handle_disconnect(params) ⇒ Object
Disconnect given peer(s).
{ method: "disconnect", params: {host: "localhost", port: 12345 }
350 351 352 353 354 |
# File 'lib/bitcoin/network/command_handler.rb', line 350 def handle_disconnect params conn = @node.connections.find {|c| c.host == params[:host] && c.port == params[:port].to_i} conn.close_connection if conn { state: :disconnected } end |
#handle_filter_monitor_output(request) ⇒ Object
Handle filter monitor output command; add given address to the list of filtered addresses in the params of the given monitor.
261 262 263 264 |
# File 'lib/bitcoin/network/command_handler.rb', line 261 def handle_filter_monitor_output request @monitors[request[:id]][:params][:addresses] << request[:address] { id: request[:id] } end |
#handle_getaddr ⇒ Object
Trigger the node to ask its for new peer addresses.
{ method: "getaddr", params: {} }
370 371 372 373 374 375 376 377 378 |
# File 'lib/bitcoin/network/command_handler.rb', line 370 def handle_getaddr conn = @node.connections.sample if conn conn.send_getaddr { state: :sent, peer: { host: conn.host, port: conn.port } } else raise "No peer connected" end end |
#handle_getblocks ⇒ Object
Trigger the node to ask its peers for new blocks.
{ method: "getblocks", params: {} }
358 359 360 361 362 363 364 365 366 |
# File 'lib/bitcoin/network/command_handler.rb', line 358 def handle_getblocks conn = @node.connections.sample if conn conn.send_getblocks { state: :sent, peer: { host: conn.host, port: conn.port } } else raise "No peer connected" end end |
#handle_help ⇒ Object
List all available commands.
bitcoin_node help
520 521 522 |
# File 'lib/bitcoin/network/command_handler.rb', line 520 def handle_help self.methods.grep(/^handle_(.*?)/).map {|m| m.to_s.sub(/^(.*?)_/, '')} end |
#handle_info ⇒ Object
Get various statistics.
bitcoin_node info
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/bitcoin/network/command_handler.rb', line 278 def handle_info blocks = @node.connections.map(&:version).compact.map(&:last_block) rescue nil established = @node.connections.select {|c| c.state == :connected } info = { blocks: { depth: @node.store.get_depth, peers: (blocks.inject{|a,b| a+=b; a } / blocks.size rescue '?' ), sync: @node.store.in_sync?, }, addrs: { alive: @node.addrs.select{|a| a.alive?}.size, total: @node.addrs.size, }, connections: { established: established.size, outgoing: established.select(&:outgoing?).size, incoming: established.select(&:incoming?).size, connecting: @node.connections.size - established.size, }, queue: @node.queue.size, inv_queue: @node.inv_queue.size, inv_cache: @node.inv_cache.size, network: @node.config[:network], storage: @node.config[:storage], version: Bitcoin.network[:protocol_version], external_ip: @node.external_ip, uptime: @node.uptime, } Bitcoin.namecoin? ? {names: @node.store.db[:names].count}.merge(info) : info end |
#handle_monitor(request, params) ⇒ Object
Handle monitor command; subscribe client to specified channels (block, tx, output, connection). Parameters can be appended to the channel name, e.g. the number of confirmations tx or output should have. Parameters are appended to the command name after an underscore (_), e.g. subscribe to channel “tx_6” to receive only transactions with 6 confirmations. You can send the last block/tx/output you know about, and it will also send you all the objects you’re missing.
Receive new blocks:
bitcoin_node monitor block
Receive blocks since block 123, and new ones as they come in:
bitcoin_node monitor block_123
Receive new (unconfirmed) transactions:
bitcoin_node monitor tx
Receive transactions with 6 confirmations:
bitcoin_node monitor tx_6
Receive transactions since <txhash>, and new ones as they come in:
bitcoin_node monitor tx_1_<txhash>
Receive [txhash, idx, address, value] for each output:
bitcoin_node monitor output
Receive outputs since <txhash>:<idx>, and new ones as they come in:
bitcoin_node monitor output_1_<txhash>:<idx>
Receive peer connections/disconnections:
bitcoin_node monitor connection"
Combine multiple channels:
bitcoin_node monitor "block tx tx_1 tx_6 connection"
NOTE: When a new block is found, it might include transactions that we didn’t previously receive as unconfirmed. To make sure you receive all transactions, also subscribe to the tx_1 channel.
100 101 102 103 |
# File 'lib/bitcoin/network/command_handler.rb', line 100 def handle_monitor request, params log.info { "Client subscribed to channel #{params[:channel].inspect}" } { id: send("handle_monitor_#{params[:channel]}", request, params) } end |
#handle_monitor_block(request, params) ⇒ Object
Handle monitor block command;
115 116 117 118 119 120 121 |
# File 'lib/bitcoin/network/command_handler.rb', line 115 def handle_monitor_block request, params monitor_id = @monitors.size id = @node.subscribe(:block) {|blk, depth| respond_monitor_block(request, blk, depth) } add_monitor(params, [[:block, id]]) respond_missed_blocks(request, monitor_id) if params[:last] monitor_id end |
#handle_monitor_connection(request, params) ⇒ Object
Handle monitor connection command; send current connections after client is subscribed to :connection channel.
268 269 270 271 272 273 274 |
# File 'lib/bitcoin/network/command_handler.rb', line 268 def handle_monitor_connection request, params id = @node.subscribe(:connection) {|data| respond(request, data) } @node.connections.select {|c| c.connected?}.each do |conn| respond(request, conn.info.merge(type: :connected)) end add_monitor(params, [[:connection, id]]) end |
#handle_monitor_output(request, params) ⇒ Object
Handle monitor output command. Receive tx hash, recipient address and value for each output. This allows easy scanning for new payments without parsing the tx format and running scripts. See #handle_monitor_tx for confirmation behavior.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/bitcoin/network/command_handler.rb', line 198 def handle_monitor_output request, params monitor_id = @monitors.size tx_id = @node.subscribe(:tx) do |tx, conf| tx.out.each.with_index do |out, idx| respond_monitor_output(request, monitor_id, tx, out, idx, conf) end end if (conf = params[:conf].to_i) > 0 block_id = @node.subscribe(:block) do |block, depth| block = @node.store.get_block_by_depth(depth - conf + 1) next unless block block.tx.each do |tx| tx.out.each.with_index do |out, idx| respond_monitor_output(request, monitor_id, tx, out, idx, conf) end end end end add_monitor(params, [[:tx, tx_id], [:block, block_id]]) respond_missed_outputs(request, monitor_id) if params[:last] monitor_id end |
#handle_monitor_reorg(request, params) ⇒ Object
TODO: params (min reorg depth)
138 139 140 141 142 143 144 |
# File 'lib/bitcoin/network/command_handler.rb', line 138 def handle_monitor_reorg request, params id = @node.subscribe(:reorg) do |new_main, new_side| respond(request, { new_main: new_main, new_side: new_side }) end add_monitor(params, [[:reorg, id]]) end |
#handle_monitor_tx(request, params) ⇒ Object
Handle monitor tx command. When conf is given, don’t subscribe to the :tx channel for unconfirmed transactions. Instead, subscribe to the :block channel, and whenever a new block comes in, send all transactions that now have conf confirmations.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/bitcoin/network/command_handler.rb', line 150 def handle_monitor_tx request, params monitor_id = @monitors.size tx_id = @node.subscribe(:tx) {|tx, conf| respond_monitor_tx(request, monitor_id, tx, conf) } conf = params[:conf].to_i block_id = @node.subscribe(:block) do |block, depth| next unless block = @node.store.get_block_by_depth(depth - conf + 1) block.tx.each {|tx| respond_monitor_tx(request, monitor_id, tx, conf) } end add_monitor(params, [[:tx, tx_id], [:block, block_id]]) respond_missed_txs(request, params, monitor_id) if params[:last] monitor_id end |
#handle_relay_tx(request, params = {}) ⇒ Object
Relay given transaction (in hex).
bitcoin_node relay_tx <tx in hex>
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
# File 'lib/bitcoin/network/command_handler.rb', line 474 def handle_relay_tx request, params = {} params[:send] ||= 3 params[:wait] ||= 3 # request, hex, send = 3, wait = 3 begin tx = Bitcoin::P::Tx.new(params[:hex].htb) rescue return respond(request, { error: "Error decoding transaction." }) end validator = tx.validator(@node.store) unless validator.validate(rules: [:syntax]) return respond(request, { error: "Transaction syntax invalid.", details: validator.error }) end unless validator.validate(rules: [:context]) return respond(request, { error: "Transaction context invalid.", details: validator.error }) end #@node.store.store_tx(tx) @node.relay_tx[tx.hash] = tx @node.relay_propagation[tx.hash] = 0 @node.connections.select(&:connected?).sample(params[:send]).each {|c| c.send_inv(:tx, tx.hash) } EM.add_timer(params[:wait]) do received = @node.relay_propagation[tx.hash] total = @node.connections.select(&:connected?).size - params[:send] percent = 100.0 / total * received respond(request, { success: true, hash: tx.hash, propagation: { received: received, sent: 1, percent: percent } }) end rescue respond(request, { error: $!., backtrace: $@ }) p $!; puts *$@ end |
#handle_rescan ⇒ Object
Trigger a rescan operation when used with a UtxoStore.
{ method: "rescan" }
392 393 394 395 396 397 398 399 400 401 |
# File 'lib/bitcoin/network/command_handler.rb', line 392 def handle_rescan EM.defer { begin @node.store.rescan rescue puts "rescan: #{$!}" end } { state: :rescanning } end |
#handle_stop ⇒ Object
Stop the bitcoin node.
bitcoin_node stop
513 514 515 516 |
# File 'lib/bitcoin/network/command_handler.rb', line 513 def handle_stop Thread.start { sleep 0.1; @node.stop } { state: :stopping } end |
#handle_store_block(params) ⇒ Object
Validate and store given block (in hex) as if it was received by a peer.
{ method: "store_block", params: { hex: <block data in hex> } }
526 527 528 529 530 |
# File 'lib/bitcoin/network/command_handler.rb', line 526 def handle_store_block params block = Bitcoin::P::Block.new(params[:hex].htb) @node.queue << [:block, block] { queued: block.hash } end |
#handle_store_tx(params) ⇒ Object
Store given transaction (in hex) as if it was received by a peer.
{ method: "store_tx", params: { hex: <tx data in hex> } }
534 535 536 537 538 |
# File 'lib/bitcoin/network/command_handler.rb', line 534 def handle_store_tx params tx = Bitcoin::P::Tx.new(params[:hex].htb) @node.queue << [:tx, tx] { queued: tx.hash } end |
#handle_tslb ⇒ Object
Get Time Since Last Block.
bitcoin_node tslb
405 406 407 |
# File 'lib/bitcoin/network/command_handler.rb', line 405 def handle_tslb { tslb: (Time.now - @node.last_block_time).to_i } end |
#handle_unmonitor(request) ⇒ Object
Handle unmonitor command; cancel given subscription. Parameter id must be the subscription ID that was returned when calling monitor.
107 108 109 110 111 112 |
# File 'lib/bitcoin/network/command_handler.rb', line 107 def handle_unmonitor request id = request[:id] raise "Monitor #{id} not found." unless @monitors[id] @monitors[id][:channels].each {|name, id| @node.unsubscribe(name, id) } { id: id } end |
#log ⇒ Object
wrap logger and append prefix
20 21 22 |
# File 'lib/bitcoin/network/command_handler.rb', line 20 def log @log ||= Bitcoin::Logger::LogWrapper.new("command:", @node.log) end |
#receive_data(data) ⇒ Object
receive request from the client
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/bitcoin/network/command_handler.rb', line 35 def receive_data data @buf.extract(data).each do |packet| begin request = symbolize_keys(JSON::parse(packet)) log.debug { request } case request[:method] when "relay_tx" return handle_relay_tx(request, request[:params]) when "monitor" respond(request, handle_monitor(request, request[:params])) else if respond_to?("handle_#{request[:method]}") if request[:params] && request[:params].any? respond(request, send("handle_#{request[:method]}", request[:params])) else respond(request, send("handle_#{request[:method]}")) end else respond(request, { error: "unknown command: #{request[:method]}. send 'help' for help." }) end end rescue respond(request, { error: $!. }) p $!; puts *$@ end end rescue p $!; puts *$@ end |
#respond(request, data) ⇒ Object
respond to a command; send serialized response to the client
25 26 27 28 29 30 31 32 |
# File 'lib/bitcoin/network/command_handler.rb', line 25 def respond(request, data) return unless data request[:result] = data request.delete(:params) @lock.synchronize do send_data(request.to_json + "\x00") end end |
#respond_missed_blocks(request, monitor_id) ⇒ Object
123 124 125 126 127 128 129 130 |
# File 'lib/bitcoin/network/command_handler.rb', line 123 def respond_missed_blocks request, monitor_id params = @monitors[monitor_id][:params] blk = @node.store.get_block(params[:last]) respond_monitor_block(request, blk) while blk = blk.get_next_block respond_monitor_block(request, blk) end end |
#respond_missed_outputs(request, monitor_id) ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/bitcoin/network/command_handler.rb', line 226 def respond_missed_outputs request, monitor_id params = @monitors[monitor_id][:params] last_hash, last_idx = *params[:last].split(":"); last_idx = last_idx.to_i return unless last_tx = @node.store.get_tx(last_hash) return unless last_out = last_tx.out[last_idx] notify = false depth = @node.store.get_depth (last_tx.get_block.depth..depth).each do |i| blk = @node.store.get_block_by_depth(i) blk.tx.each do |tx| tx.out.each.with_index do |out, idx| if notify respond_monitor_output(request, monitor_id, tx, out, idx, (depth - blk.depth + 1)) else notify = true if tx.hash == last_hash && idx == last_idx end end end end end |
#respond_missed_txs(request, params, monitor_id) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/bitcoin/network/command_handler.rb', line 167 def respond_missed_txs request, params, monitor_id return unless last_tx = @node.store.get_tx(params[:last]) notify = false; depth = @node.store.get_depth (last_tx.get_block.depth..depth).each do |i| blk = @node.store.get_block_by_depth(i) blk.tx.each do |tx| respond_monitor_tx(request, monitor_id, tx, (depth - blk.depth + 1)) if notify notify = true if tx.hash == last_tx.hash end end end |
#respond_monitor_block(request, block, depth = nil) ⇒ Object
132 133 134 135 |
# File 'lib/bitcoin/network/command_handler.rb', line 132 def respond_monitor_block request, block, depth = nil depth ||= block.depth respond(request, { hash: block.hash, hex: block.to_payload.hth, depth: depth }) end |
#respond_monitor_output(request, monitor_id, tx, out, idx, conf) ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/bitcoin/network/command_handler.rb', line 247 def respond_monitor_output request, monitor_id, tx, out, idx, conf addr = out.parsed_script.get_address params = @monitors[monitor_id][:params] # filter by addresses return if params[:addresses] && !params[:addresses].include?(addr) respond(request, { nhash: tx.nhash, hash: tx.hash, idx: idx, address: addr, value: out.value, conf: conf }) end |
#respond_monitor_tx(request, monitor_id, tx, conf = nil) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/bitcoin/network/command_handler.rb', line 179 def respond_monitor_tx request, monitor_id, tx, conf = nil conf ||= tx.confirmations params = @monitors[monitor_id][:params] # filter by addresses if params[:addresses] addrs = tx.out.map(&:parsed_script).map(&:get_address) return unless (params[:addresses] & addrs).any? end respond(request, { hash: tx.hash, nhash: tx.nhash, hex: tx.to_payload.hth, conf: conf }) end |
#unbind ⇒ Object
disconnect notification clients when connection is closed
549 550 551 552 |
# File 'lib/bitcoin/network/command_handler.rb', line 549 def unbind #@node.notifiers.unsubscribe(@notify_sid) if @notify_sid @node.command_connections.delete(self) end |