Class: Tapyrus::Network::Peer
- Inherits:
-
Object
- Object
- Tapyrus::Network::Peer
- Defined in:
- lib/tapyrus/network/peer.rb
Overview
remote peer class.
Constant Summary collapse
- PING_INTERVAL =
Interval for pinging peers.
2 * 60
Instance Attribute Summary collapse
-
#best_hash ⇒ Object
Returns the value of attribute best_hash.
-
#best_height ⇒ Object
Returns the value of attribute best_height.
-
#bytes_recv ⇒ Object
Returns the value of attribute bytes_recv.
-
#bytes_sent ⇒ Object
Returns the value of attribute bytes_sent.
-
#chain ⇒ Object
readonly
Returns the value of attribute chain.
-
#conn ⇒ Object
remote peer connection.
-
#conn_time ⇒ Object
Returns the value of attribute conn_time.
-
#connected ⇒ Object
Returns the value of attribute connected.
-
#fee_rate ⇒ Object
Returns the value of attribute fee_rate.
-
#host ⇒ Object
readonly
remote peer info.
-
#id ⇒ Object
Returns the value of attribute id.
-
#last_ping ⇒ Object
Returns the value of attribute last_ping.
-
#last_ping_nonce ⇒ Object
Returns the value of attribute last_ping_nonce.
-
#last_pong ⇒ Object
Returns the value of attribute last_pong.
-
#last_recv ⇒ Object
Returns the value of attribute last_recv.
-
#last_send ⇒ Object
Returns the value of attribute last_send.
-
#local_version ⇒ Object
Returns the value of attribute local_version.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#min_ping ⇒ Object
Returns the value of attribute min_ping.
-
#outbound ⇒ Object
TODO need implements to accept inbound connection.
-
#pool ⇒ Object
readonly
parent pool.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#primary ⇒ Object
Returns the value of attribute primary.
Instance Method Summary collapse
- #addr ⇒ Object
-
#block_type ⇒ Object
get peer’s block type.
-
#broadcast_tx(tx) ⇒ Object
broadcast tx.
-
#close(msg = "") ⇒ Object
close peer connection.
- #connect ⇒ Object
- #connected? ⇒ Boolean
-
#handle_block_inv(hashes) ⇒ Object
handle block inv message.
-
#handle_error(e) ⇒ Object
handle error.
-
#handle_headers(headers) ⇒ Object
handle headers message.
- #handle_merkle_block(merkle_block) ⇒ Object
- #handle_tx(tx) ⇒ Object
-
#initialize(host, port, pool, configuration) ⇒ Peer
constructor
A new instance of Peer.
- #outbound? ⇒ Boolean
-
#ping_time ⇒ Object
calculate ping-pong time.
- #post_handshake ⇒ Object
-
#primary? ⇒ Boolean
Whether to try and download blocks and transactions from this peer.
-
#remote_version ⇒ Tapyrus::Message::Version
get remote peer’s version message.
-
#send_addrs ⇒ Object
send
addr
message to remote peer. -
#send_filter_add(element) ⇒ Object
send filteradd message.
-
#send_filter_clear ⇒ Object
send filterclear message.
-
#send_filter_load(bloom) ⇒ Object
send filterload message.
-
#send_ping ⇒ Object
send ping message.
-
#start_block_header_download ⇒ Object
start block header download.
-
#to_network_addr ⇒ Tapyrus::Message::NetworkAddr
generate Tapyrus::Message::NetworkAddr object from this peer info.
- #unbind ⇒ Object
Constructor Details
#initialize(host, port, pool, configuration) ⇒ Peer
Returns a new instance of Peer.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/tapyrus/network/peer.rb', line 38 def initialize(host, port, pool, configuration) @host = host @port = port @pool = pool @chain = pool.chain @connected = false @primary = false @logger = Tapyrus::Logger.create(:debug) @outbound = true @best_hash = -1 @best_height = -1 @min_ping = -1 @bytes_sent = 0 @bytes_recv = 0 @relay = configuration.conf[:relay] current_height = @chain.latest_block.height remote_addr = Tapyrus::Message::NetworkAddr.new(ip: host, port: port, time: nil) @local_version = Tapyrus::Message::Version.new(remote_addr: remote_addr, start_height: current_height, relay: @relay) end |
Instance Attribute Details
#best_hash ⇒ Object
Returns the value of attribute best_hash.
21 22 23 |
# File 'lib/tapyrus/network/peer.rb', line 21 def best_hash @best_hash end |
#best_height ⇒ Object
Returns the value of attribute best_height.
22 23 24 |
# File 'lib/tapyrus/network/peer.rb', line 22 def best_height @best_height end |
#bytes_recv ⇒ Object
Returns the value of attribute bytes_recv.
14 15 16 |
# File 'lib/tapyrus/network/peer.rb', line 14 def bytes_recv @bytes_recv end |
#bytes_sent ⇒ Object
Returns the value of attribute bytes_sent.
13 14 15 |
# File 'lib/tapyrus/network/peer.rb', line 13 def bytes_sent @bytes_sent end |
#chain ⇒ Object (readonly)
Returns the value of attribute chain.
35 36 37 |
# File 'lib/tapyrus/network/peer.rb', line 35 def chain @chain end |
#conn ⇒ Object
remote peer connection
29 30 31 |
# File 'lib/tapyrus/network/peer.rb', line 29 def conn @conn end |
#conn_time ⇒ Object
Returns the value of attribute conn_time.
15 16 17 |
# File 'lib/tapyrus/network/peer.rb', line 15 def conn_time @conn_time end |
#connected ⇒ Object
Returns the value of attribute connected.
30 31 32 |
# File 'lib/tapyrus/network/peer.rb', line 30 def connected @connected end |
#fee_rate ⇒ Object
Returns the value of attribute fee_rate.
36 37 38 |
# File 'lib/tapyrus/network/peer.rb', line 36 def fee_rate @fee_rate end |
#host ⇒ Object (readonly)
remote peer info
25 26 27 |
# File 'lib/tapyrus/network/peer.rb', line 25 def host @host end |
#id ⇒ Object
Returns the value of attribute id.
9 10 11 |
# File 'lib/tapyrus/network/peer.rb', line 9 def id @id end |
#last_ping ⇒ Object
Returns the value of attribute last_ping.
16 17 18 |
# File 'lib/tapyrus/network/peer.rb', line 16 def last_ping @last_ping end |
#last_ping_nonce ⇒ Object
Returns the value of attribute last_ping_nonce.
17 18 19 |
# File 'lib/tapyrus/network/peer.rb', line 17 def last_ping_nonce @last_ping_nonce end |
#last_pong ⇒ Object
Returns the value of attribute last_pong.
18 19 20 |
# File 'lib/tapyrus/network/peer.rb', line 18 def last_pong @last_pong end |
#last_recv ⇒ Object
Returns the value of attribute last_recv.
12 13 14 |
# File 'lib/tapyrus/network/peer.rb', line 12 def last_recv @last_recv end |
#last_send ⇒ Object
Returns the value of attribute last_send.
11 12 13 |
# File 'lib/tapyrus/network/peer.rb', line 11 def last_send @last_send end |
#local_version ⇒ Object
Returns the value of attribute local_version.
10 11 12 |
# File 'lib/tapyrus/network/peer.rb', line 10 def local_version @local_version end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
8 9 10 |
# File 'lib/tapyrus/network/peer.rb', line 8 def logger @logger end |
#min_ping ⇒ Object
Returns the value of attribute min_ping.
19 20 21 |
# File 'lib/tapyrus/network/peer.rb', line 19 def min_ping @min_ping end |
#outbound ⇒ Object
TODO need implements to accept inbound connection
20 21 22 |
# File 'lib/tapyrus/network/peer.rb', line 20 def outbound @outbound end |
#pool ⇒ Object (readonly)
parent pool
34 35 36 |
# File 'lib/tapyrus/network/peer.rb', line 34 def pool @pool end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
26 27 28 |
# File 'lib/tapyrus/network/peer.rb', line 26 def port @port end |
#primary ⇒ Object
Returns the value of attribute primary.
31 32 33 |
# File 'lib/tapyrus/network/peer.rb', line 31 def primary @primary end |
Instance Method Details
#addr ⇒ Object
71 72 73 |
# File 'lib/tapyrus/network/peer.rb', line 71 def addr "#{host}:#{port}" end |
#block_type ⇒ Object
get peer’s block type.
109 110 111 |
# File 'lib/tapyrus/network/peer.rb', line 109 def block_type Tapyrus::Message::Inventory::MSG_FILTERED_BLOCK # TODO need other implementation end |
#broadcast_tx(tx) ⇒ Object
broadcast tx.
104 105 106 |
# File 'lib/tapyrus/network/peer.rb', line 104 def broadcast_tx(tx) conn.(Tapyrus::Message::Tx.new(tx)) end |
#close(msg = "") ⇒ Object
close peer connection.
149 150 151 |
# File 'lib/tapyrus/network/peer.rb', line 149 def close(msg = "") conn.close(msg) end |
#connect ⇒ Object
59 60 61 |
# File 'lib/tapyrus/network/peer.rb', line 59 def connect self.conn ||= EM.connect(host, port, Tapyrus::Network::Connection, self) end |
#connected? ⇒ Boolean
63 64 65 |
# File 'lib/tapyrus/network/peer.rb', line 63 def connected? @connected end |
#handle_block_inv(hashes) ⇒ Object
handle block inv message.
167 168 169 170 |
# File 'lib/tapyrus/network/peer.rb', line 167 def handle_block_inv(hashes) getdata = Tapyrus::Message::GetData.new(hashes.map { |h| Tapyrus::Message::Inventory.new(block_type, h) }) conn.(getdata) end |
#handle_error(e) ⇒ Object
handle error
140 141 142 |
# File 'lib/tapyrus/network/peer.rb', line 140 def handle_error(e) pool.handle_error(e) end |
#handle_headers(headers) ⇒ Object
handle headers message
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/tapyrus/network/peer.rb', line 126 def handle_headers(headers) headers.headers.each do |header| break unless header.valid? entry = chain.append_header(header) next unless entry @best_hash = entry.block_hash @best_height = entry.height end pool.changed pool.notify_observers(:header, { hash: @best_hash, height: @best_height }) start_block_header_download if headers.headers.size > 0 # next header download end |
#handle_merkle_block(merkle_block) ⇒ Object
177 178 179 180 |
# File 'lib/tapyrus/network/peer.rb', line 177 def handle_merkle_block(merkle_block) pool.changed pool.notify_observers(:merkleblock, merkle_block) end |
#handle_tx(tx) ⇒ Object
172 173 174 175 |
# File 'lib/tapyrus/network/peer.rb', line 172 def handle_tx(tx) pool.changed pool.notify_observers(:tx, tx) end |
#outbound? ⇒ Boolean
67 68 69 |
# File 'lib/tapyrus/network/peer.rb', line 67 def outbound? @outbound end |
#ping_time ⇒ Object
calculate ping-pong time.
76 77 78 |
# File 'lib/tapyrus/network/peer.rb', line 76 def ping_time last_pong ? (last_pong - last_ping) / 1e6 : -1 end |
#post_handshake ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'lib/tapyrus/network/peer.rb', line 86 def post_handshake @connected = true pool.handle_new_peer(self) # require remote peer to use headers message instead fo inv message. conn.(Tapyrus::Message::SendHeaders.new) EM.add_periodic_timer(PING_INTERVAL) { send_ping } end |
#primary? ⇒ Boolean
Whether to try and download blocks and transactions from this peer.
120 121 122 |
# File 'lib/tapyrus/network/peer.rb', line 120 def primary? primary end |
#remote_version ⇒ Tapyrus::Message::Version
get remote peer’s version message.
115 116 117 |
# File 'lib/tapyrus/network/peer.rb', line 115 def remote_version conn.version end |
#send_addrs ⇒ Object
send addr
message to remote peer
161 162 163 164 |
# File 'lib/tapyrus/network/peer.rb', line 161 def send_addrs addrs = pool.peers.select { |p| p != self }.map(&:to_network_addr) conn.(Tapyrus::Message::Addr.new(addrs)) end |
#send_filter_add(element) ⇒ Object
send filteradd message.
198 199 200 201 |
# File 'lib/tapyrus/network/peer.rb', line 198 def send_filter_add(element) filter_add = Tapyrus::Message::FilterAdd.new(element) conn.(filter_add) end |
#send_filter_clear ⇒ Object
send filterclear message.
204 205 206 207 |
# File 'lib/tapyrus/network/peer.rb', line 204 def send_filter_clear filter_clear = Tapyrus::Message::FilterClear.new conn.(filter_clear) end |
#send_filter_load(bloom) ⇒ Object
send filterload message.
192 193 194 195 |
# File 'lib/tapyrus/network/peer.rb', line 192 def send_filter_load(bloom) filter_load = Tapyrus::Message::FilterLoad.new(bloom, Tapyrus::Message::FilterLoad::BLOOM_UPDATE_ALL) conn.(filter_load) end |
#send_ping ⇒ Object
send ping message.
183 184 185 186 187 188 189 |
# File 'lib/tapyrus/network/peer.rb', line 183 def send_ping ping = Tapyrus::Message::Ping.new @last_ping = Time.now.to_i @last_pong = -1 @last_ping_nonce = ping.nonce conn.(ping) end |
#start_block_header_download ⇒ Object
start block header download
96 97 98 99 100 101 |
# File 'lib/tapyrus/network/peer.rb', line 96 def start_block_header_download logger.info("[#{addr}] start block header download.") get_headers = Tapyrus::Message::GetHeaders.new(Tapyrus.chain_params.protocol_version, [chain.latest_block.block_hash]) conn.(get_headers) end |
#to_network_addr ⇒ Tapyrus::Message::NetworkAddr
generate Tapyrus::Message::NetworkAddr object from this peer info.
155 156 157 158 |
# File 'lib/tapyrus/network/peer.rb', line 155 def to_network_addr v = remote_version Tapyrus::Message::NetworkAddr.new(ip: host, port: port, services: v.services, time: v.) end |
#unbind ⇒ Object
144 145 146 |
# File 'lib/tapyrus/network/peer.rb', line 144 def unbind pool.handle_close_peer(self) end |