class Ciri::P2P::Peer

represent a connected remote node

Constants

INCOMING
OUTGOING

Attributes

connection[R]
direction[R]

Public Class Methods

new(connection, handshake, protocols, direction:) click to toggle source
# File lib/ciri/p2p/peer.rb, line 40
def initialize(connection, handshake, protocols, direction:)
  @connection = connection
  @handshake = handshake
  @protocols = protocols
  @protocol_io_hash = make_protocol_io_hash(protocols, handshake.caps, connection)
  @direction = direction
end

Public Instance Methods

==(peer) click to toggle source
# File lib/ciri/p2p/peer.rb, line 70
def ==(peer)
  self.class == peer.class && raw_node_id == peer.raw_node_id
end
Also aliased as: eql?
disconnect() click to toggle source

disconnect peer connections

# File lib/ciri/p2p/peer.rb, line 87
def disconnect
  @connection.close
end
disconnected?() click to toggle source
# File lib/ciri/p2p/peer.rb, line 91
def disconnected?
  @connection.closed?
end
eql?(peer)
Alias for: ==
find_protocol(name) click to toggle source
# File lib/ciri/p2p/peer.rb, line 99
def find_protocol(name)
  @protocol.find do |protocol|
    protocol.name == name
  end
end
find_protocol_io(name) click to toggle source
# File lib/ciri/p2p/peer.rb, line 105
def find_protocol_io(name)
  protocol_ios.find do |protocol_io|
    protocol_io.protocol.name == name
  end
end
find_protocol_io_by_msg_code(raw_code) click to toggle source

find ProtocolIO by raw message code used by DEVP2P to find stream of sub-protocol

# File lib/ciri/p2p/peer.rb, line 113
def find_protocol_io_by_msg_code(raw_code)
  @protocol_io_hash.values.find do |protocol_io|
    offset = protocol_io.offset
    protocol = protocol_io.protocol
    raw_code >= offset && raw_code < offset + protocol.length
  end
end
hash() click to toggle source
# File lib/ciri/p2p/peer.rb, line 66
def hash
  raw_node_id.hash
end
incoming?() click to toggle source
# File lib/ciri/p2p/peer.rb, line 52
def incoming?
  @direction == INCOMING
end
inspect() click to toggle source
# File lib/ciri/p2p/peer.rb, line 62
def inspect
  "<Peer:#{to_s} direction: #{@direction}>"
end
node_id() click to toggle source

get NodeID object

# File lib/ciri/p2p/peer.rb, line 82
def node_id
  @node_id ||= NodeID.from_raw_id(@handshake.id)
end
outgoing?() click to toggle source
# File lib/ciri/p2p/peer.rb, line 48
def outgoing?
  @direction == OUTGOING
end
protocol_ios() click to toggle source
# File lib/ciri/p2p/peer.rb, line 95
def protocol_ios
  @protocol_io_hash.values
end
raw_node_id() click to toggle source

get id of node in bytes form

# File lib/ciri/p2p/peer.rb, line 77
def raw_node_id
  node_id.to_bytes
end
to_s() click to toggle source
# File lib/ciri/p2p/peer.rb, line 56
def to_s
  @display_name ||= begin
    Utils.to_hex(node_id.id)[0..8]
  end
end

Private Instance Methods

make_protocol_io_hash(protocols, caps, io) click to toggle source

return protocol_io_hash handle multiple sub protocols upon one io

# File lib/ciri/p2p/peer.rb, line 125
def make_protocol_io_hash(protocols, caps, io)
  # sub protocol offset
  offset = RLPX::BASE_PROTOCOL_LENGTH
  result = {}
  # [name, version] as key
  protocols_hash = protocols.map {|protocol| [[protocol.name, protocol.version], protocol]}.to_h
  sorted_caps = caps.sort_by {|c| [c.name, c.version]}

  sorted_caps.each do |cap|
    protocol = protocols_hash[[cap.name, cap.version]]
    next unless protocol
    # ignore same name old protocols
    if (old = result[cap.name])
      result.delete(cap.name)
      offset -= old.protocol.length
    end
    result[cap.name] = ProtocolIO.new(protocol, offset, io)
    # move offset, to support next protocol
    offset += protocol.length
  end
  result
end