class Ciri::P2P::Server
P2P
Server
maintain connection, node discovery, rlpx handshake
Constants
- DEFAULT_DIAL_RATIO
- DEFAULT_MAX_PENDING_PEERS
Attributes
dial_scheduler[R]
dialer[R]
handshake[R]
local_address[R]
tcp_port[R]
Public Class Methods
new(private_key:, protocols:, bootnodes: [], node_name: 'Ciri', host: '127.0.0.1', tcp_port: 33033, udp_port: 33033, max_outgoing: 10, max_incoming:10, ping_interval_secs: 15, discovery_interval_secs: 15, dial_outgoing_interval_secs: 25)
click to toggle source
# File lib/ciri/p2p/server.rb, line 56 def initialize(private_key:, protocols:, bootnodes: [], node_name: 'Ciri', host: '127.0.0.1', tcp_port: 33033, udp_port: 33033, max_outgoing: 10, max_incoming:10, ping_interval_secs: 15, discovery_interval_secs: 15, dial_outgoing_interval_secs: 25) @private_key = private_key @node_name = node_name # prepare handshake information @local_node_id = NodeID.new(@private_key) caps = protocols.map do |protocol| Cap.new(name: protocol.name, version: protocol.version) end @handshake = ProtocolHandshake.new(version: BASE_PROTOCOL_VERSION, name: @node_name, id: @local_node_id.id, caps: caps) @host = host @tcp_port = tcp_port @udp_port = udp_port @dialer = Dialer.new(private_key: private_key, handshake: @handshake) @peer_store = PeerStore.new @network_state = NetworkState.new( protocols: protocols, peer_store: @peer_store, local_node_id: @local_node_id, max_incoming: max_incoming, max_outgoing: max_outgoing, ping_interval_secs: ping_interval_secs) @bootnodes = bootnodes @discovery_interval_secs = discovery_interval_secs @dial_outgoing_interval_secs = dial_outgoing_interval_secs end
Public Instance Methods
run()
click to toggle source
return reactor to wait
# File lib/ciri/p2p/server.rb, line 98 def run # setup bootnodes @bootnodes.each do |node| @peer_store.add_bootnode(node) end # start server and services Async::Reactor.run do |task| # initialize protocols @network_state.initialize_protocols # wait sub tasks task.async do task.async do # Wait for server started listen # we use listened port to start DiscoveryService to allow 0 port task.sleep(0.5) until @local_address # start discovery service @discovery_service = Discovery::Service.new( peer_store: @peer_store, private_key: @private_key, host: @host, udp_port: @udp_port, tcp_port: @tcp_port, discovery_interval_secs: @discovery_interval_secs) task.async { @discovery_service.run } # start dial outgoing nodes @dial_scheduler = DialScheduler.new( @network_state, @dialer, dial_outgoing_interval_secs: @dial_outgoing_interval_secs) task.async {@dial_scheduler.run} end task.async {start_listen} end.wait end end
start_listen(task: Async::Task.current)
click to toggle source
start listen and accept clients
# File lib/ciri/p2p/server.rb, line 136 def start_listen(task: Async::Task.current) endpoint = Async::IO::Endpoint.tcp(@host, @tcp_port) endpoint.bind do |socket| @local_address = socket.local_address info("start accept connections -- listen on #{@local_address.getnameinfo.join(":")}") # update tcp_port if it is 0 if @tcp_port.zero? @tcp_port = @local_address.ip_port end socket.listen(Socket::SOMAXCONN) loop do client, addrinfo = socket.accept c = Connection.new(client) c.encryption_handshake!(private_key: @private_key) remote_handshake = c.protocol_handshake!(handshake) @network_state.new_peer_connected(c, remote_handshake, direction: Peer::INCOMING) end end end
to_node()
click to toggle source
# File lib/ciri/p2p/server.rb, line 92 def to_node address = Address.new(ip: @host, tcp_port: tcp_port, udp_port: udp_port) Node.new(node_id: @local_node_id, addresses: [address]) end
udp_port()
click to toggle source
# File lib/ciri/p2p/server.rb, line 88 def udp_port @discovery_service&.udp_port || @udp_port end