Class: Ciri::P2P::NetworkState

Inherits:
Object
  • Object
show all
Includes:
Utils::Logger
Defined in:
lib/ciri/p2p/network_state.rb

Overview

NetworkState maintaining current connected peers

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(protocols:, peer_store:, local_node_id:, max_outgoing: 10, max_incoming: 10, ping_interval_secs: 15) ⇒ NetworkState

Returns a new instance of NetworkState.



42
43
44
45
46
47
48
49
50
51
# File 'lib/ciri/p2p/network_state.rb', line 42

def initialize(protocols:, peer_store:, local_node_id:, max_outgoing: 10, max_incoming: 10, ping_interval_secs: 15)
  @peers = {}
  @peers_lock = Async::Semaphore.new
  @peer_store = peer_store
  @protocols = protocols
  @local_node_id = local_node_id
  @max_outgoing = max_outgoing
  @max_incoming = max_incoming
  @ping_interval_secs = ping_interval_secs
end

Instance Attribute Details

#capsObject (readonly)

Returns the value of attribute caps.



40
41
42
# File 'lib/ciri/p2p/network_state.rb', line 40

def caps
  @caps
end

#local_node_idObject (readonly)

Returns the value of attribute local_node_id.



40
41
42
# File 'lib/ciri/p2p/network_state.rb', line 40

def local_node_id
  @local_node_id
end

#peer_storeObject (readonly)

Returns the value of attribute peer_store.



40
41
42
# File 'lib/ciri/p2p/network_state.rb', line 40

def peer_store
  @peer_store
end

#peersObject (readonly)

Returns the value of attribute peers.



40
41
42
# File 'lib/ciri/p2p/network_state.rb', line 40

def peers
  @peers
end

Instance Method Details

#disconnect_allObject



102
103
104
105
106
107
# File 'lib/ciri/p2p/network_state.rb', line 102

def disconnect_all
  debug("[#{local_node_id.short_hex}] disconnect all")
  peers.each_value do |peer|
    disconnect_peer(peer, reason: "disconnect all...")
  end
end

#disconnect_peer(peer, reason: nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ciri/p2p/network_state.rb', line 88

def disconnect_peer(peer, reason: nil)
  @peers_lock.acquire do
    # only disconnect from peers if direction correct to avoiding delete peer by mistake
    if (exist_peer = @peers[peer.raw_node_id]) && exist_peer.direction == peer.direction
      info("[#{local_node_id.short_hex}] disconnect peer: #{peer.inspect}, reason: #{reason}")
      remove_peer(peer)
      peer.disconnect
      @peer_store.update_peer_status(peer.raw_node_id, PeerStore::Status::DISCONNECTED)
    else
      debug("[#{local_node_id.short_hex}] Ignoring: disconnect peer: #{peer.inspect}, reason: #{reason}")
    end
  end
end

#initialize_protocols(task: Async::Task.current) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/ciri/p2p/network_state.rb', line 53

def initialize_protocols(task: Async::Task.current)
  # initialize protocols
  @protocols.each do |protocol|
    context = ProtocolContext.new(self, protocol: protocol)
    task.async {protocol.initialized(context)}
  end
end

#new_peer_connected(connection, handshake, direction:, task: Async::Task.current) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ciri/p2p/network_state.rb', line 65

def new_peer_connected(connection, handshake, direction:, task: Async::Task.current)
  @peers_lock.acquire do
    peer = Peer.new(connection, handshake, @protocols, direction: direction)
    # disconnect already connected peers
    if @peers.include?(peer.raw_node_id)
      debug("[#{local_node_id.short_hex}] peer #{peer.inspect} is already connected")
      # disconnect duplicate connection
      peer.disconnect
      return
    end
    # check peers
    protocol_handshake_checks(handshake)
    @peers[peer.raw_node_id] = peer
    info "[#{local_node_id.short_hex}] connect to new peer #{peer.inspect}"
    @peer_store.update_peer_status(peer.raw_node_id, PeerStore::Status::CONNECTED)
    # run peer logic
    task.async do
      register_peer_protocols(peer)
      handling_peer(peer)
    end
  end
end

#number_of_attemp_outgoingObject



61
62
63
# File 'lib/ciri/p2p/network_state.rb', line 61

def number_of_attemp_outgoing
  @max_outgoing - @peers.values.select(&:outgoing?).count
end