Class: Bitcoin::Network::Handler

Inherits:
EM::Connection
  • Object
show all
Includes:
Bitcoin, Storage
Defined in:
lib/bitcoin/network/handler.rb

Constant Summary

Constant Summary

Constants included from Bitcoin

Bitcoin::NETWORKS, VERSION

Instance Method Summary (collapse)

Methods included from Storage

log

Methods included from Bitcoin

network, network=

Methods included from Util

#address_checksum?, #address_version, #base58_to_int, #bitcoin_elliptic_curve, #bitcoin_hash, #bitcoin_mrkl, #block_hash, #checksum, #decode_compact_bits, #decode_target, #encode_base58, #encode_compact_bits, #generate_address, #generate_key, #hash160, #hash160_from_address, #hash160_to_address, #hash_mrkl_tree, #inspect_key, #int_to_base58, #open_key, #pubkey_to_address, #sha256, #sign_data, #valid_address?, #verify_signature

Constructor Details

- (Handler) initialize(node, host, port)

A new instance of Handler



15
16
17
18
19
# File 'lib/bitcoin/network/handler.rb', line 15

def initialize node, host, port
  @node, @host, @port = node, host, port
  @parser = Bitcoin::Protocol::Parser.new(self)
  @state = :new
end

Instance Method Details

- (Object) get_genesis_block



107
108
109
110
111
# File 'lib/bitcoin/network/handler.rb', line 107

def get_genesis_block
  log.info { "Asking for genesis block" }
  pkt = Protocol.getdata_pkt(:block, [htb(Bitcoin::network[:genesis_hash])])
  send_data(pkt)
end

- (Object) htb(h)



11
# File 'lib/bitcoin/network/handler.rb', line 11

def htb(h); [h].pack("H*"); end

- (Object) hth(h)



10
# File 'lib/bitcoin/network/handler.rb', line 10

def hth(h); h.unpack("H*")[0]; end

- (Object) log



13
# File 'lib/bitcoin/network/handler.rb', line 13

def log; @node.log; end

- (Object) on_addr(addr)



62
63
64
# File 'lib/bitcoin/network/handler.rb', line 62

def on_addr(addr)
  log.info { ">> addr: #{addr} #{addr.alive?}" }
end

- (Object) on_block(blk)



70
71
72
73
# File 'lib/bitcoin/network/handler.rb', line 70

def on_block(blk)
  log.info { ">> block: #{blk.hash} (#{blk.payload.size} bytes)" }
  @node.queue << blk
end

- (Object) on_get_block(hash)



58
59
60
# File 'lib/bitcoin/network/handler.rb', line 58

def on_get_block(hash)
  log.info { ">> get block: #{hth(hash)}" }
end

- (Object) on_get_transaction(hash)



54
55
56
# File 'lib/bitcoin/network/handler.rb', line 54

def on_get_transaction(hash)
  log.info { ">> get transaction: #{hth(hash)}" }
end

- (Object) on_handshake_begin



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/bitcoin/network/handler.rb', line 113

def on_handshake_begin
  @state = :handshake
  block   = @node.store.get_depth
  from    = "127.0.0.1:8333"
  from_id = Bitcoin::Protocol::Uniq
  to      = "#{@node.host}:#{@node.port}"

  pkt = Protocol.version_pkt(from_id, from, to, block)
  log.info { "<< version (#{Bitcoin::Protocol::VERSION})" }
  send_data(pkt)
end

- (Object) on_handshake_complete



91
92
93
94
95
# File 'lib/bitcoin/network/handler.rb', line 91

def on_handshake_complete
  log.debug { "handshake complete" }
  @state = :connected
  query_blocks
end

- (Object) on_inv_block(hash)



47
48
49
50
51
52
# File 'lib/bitcoin/network/handler.rb', line 47

def on_inv_block(hash)
  log.info { ">> inv block: #{hth(hash)}" }
  pkt = Protocol.getdata_pkt(:block, [hash])
  log.info { "<< getdata block: #{hth(hash)}" }
  send_data(pkt)
end

- (Object) on_inv_transaction(hash)



40
41
42
43
44
45
# File 'lib/bitcoin/network/handler.rb', line 40

def on_inv_transaction(hash)
  log.info { ">> inv transaction: #{hth(hash)}" }
  pkt = Protocol.getdata_pkt(:tx, [hash])
  log.info { "<< getdata tx: #{hth(hash)}" }
  send_data(pkt)
end

- (Object) on_tx(tx)



66
67
68
# File 'lib/bitcoin/network/handler.rb', line 66

def on_tx(tx)
  log.info { ">> tx: #{tx.hash} (#{tx.payload.size} bytes)" }
end

- (Object) on_verack



86
87
88
89
# File 'lib/bitcoin/network/handler.rb', line 86

def on_verack
  log.info { ">> verack" }
  on_handshake_complete  if @state == :handshake
end

- (Object) on_version(version)



75
76
77
78
79
80
81
82
83
84
# File 'lib/bitcoin/network/handler.rb', line 75

def on_version(version)
  log.info { ">> version: #{version.inspect}" }

  @node.block = version.block # temp..

  log.info { "<< verack" }
  send_data( Protocol.verack_pkt )
  
  on_handshake_complete
end

- (Object) post_init



21
22
23
24
25
26
# File 'lib/bitcoin/network/handler.rb', line 21

def post_init
  log.info { "Connected to #{@host}:#{@port}" }
  @state = :established
  @node.connections << self
  on_handshake_begin
end

- (Object) query_blocks



97
98
99
100
101
102
103
104
105
# File 'lib/bitcoin/network/handler.rb', line 97

def query_blocks
#      return get_genesis_block
  locator = @node.store.get_locator
#      return get_genesis_block  unless locator
  pkt = Protocol.pkt("getblocks", [Bitcoin::network[:magic_head],
      locator.size.chr, *locator.map{|l| htb(l).reverse}, "\x00"*32].join)
  log.info { "<< getblocks: #{locator.first}" }
  send_data(pkt)
end

- (Object) receive_data(data)



28
29
30
31
# File 'lib/bitcoin/network/handler.rb', line 28

def receive_data data
  log.debug { "Receiving data (#{data.size} bytes)" }
  @parser.parse(data)
end

- (Object) unbind



33
34
35
36
37
# File 'lib/bitcoin/network/handler.rb', line 33

def unbind
  log.info { "Disconnected #{@host}:#{@port}" }
  @state = :disconnected
  @node.connections.delete(self)
end