diff --git a/lib/remote_node.go b/lib/remote_node.go index 174389192..50dcf5355 100644 --- a/lib/remote_node.go +++ b/lib/remote_node.go @@ -12,13 +12,13 @@ import ( "time" ) -type RemoteNodeConnectionStatus int +type RemoteNodeStatus int const ( - RemoteNodeConnectionStatus_NotConnected RemoteNodeConnectionStatus = 0 - RemoteNodeConnectionStatus_Connected RemoteNodeConnectionStatus = 1 - RemoteNodeConnectionStatus_Attempted RemoteNodeConnectionStatus = 2 - RemoteNodeConnectionStatus_Terminated RemoteNodeConnectionStatus = 3 + RemoteNodeStatus_NotConnected RemoteNodeStatus = 0 + RemoteNodeStatus_Connected RemoteNodeStatus = 1 + RemoteNodeStatus_Attempted RemoteNodeStatus = 2 + RemoteNodeStatus_Terminated RemoteNodeStatus = 3 ) type RemoteNodeId uint64 @@ -31,10 +31,29 @@ func (id RemoteNodeId) ToUint64() uint64 { return uint64(id) } +// RemoteNode is a consensus-aware wrapper around the network Peer object. It is used to manage the lifecycle of a peer +// and to store consensus-related metadata about the peer. The RemoteNode can wrap around either an inbound or outbound +// peer connection. For outbound peers, the RemoteNode is created prior to the connection being established. In this case, +// the RemoteNode will be first used to initiate an OutboundConnectionAttempt, and then store the resulting connected peer. +// For inbound peers, the RemoteNode is created after the connection is established in ConnectionManager. These connected +// peers are signaled to the RemoteNode via the SetPeer method. +// +// Once the RemoteNode's peer is set, the RemoteNode is used to manage the handshake with the peer. The handshake involves +// rounds of Version and Verack messages being sent between our node and the peer. The handshake is complete when both +// nodes have sent and received a Version and Verack message. Once the handshake is successful, the RemoteNode will +// emit a MsgDeSoPeerHandshakeComplete control message via the Server. +// +// In steady state, i.e. after the handshake is complete, the RemoteNode can be used to send a message to the peer, +// retrieve the peer's handshake metadata, and close the connection with the peer. The RemoteNode has a single-use +// lifecycle. Once the RemoteNode is terminated, it will be disposed of, and a new RemoteNode must be created if we +// wish to reconnect to the peer in the future. type RemoteNode struct { - peer *Peer + peer *Peer + // The id is the unique identifier of this RemoteNode. For outbound connections, the id will be the same as the + // attemptId of the OutboundConnectionAttempt, and the subsequent id of the outbound peer. For inbound connections, + // the id will be the same as the inbound peer's id. id RemoteNodeId - connectionStatus RemoteNodeConnectionStatus + connectionStatus RemoteNodeStatus params *DeSoParams srv *Server @@ -45,8 +64,11 @@ type RemoteNode struct { hyperSync bool posValidator bool + // handshakeMetadata is used to store the information received from the peer during the handshake. handshakeMetadata *HandshakeMetadata - keystore *BLSKeystore + // keystore is a reference to the node's BLS private key storage. In the context of a RemoteNode, the keystore is + // used in the Verack message for validator nodes to prove ownership of the validator BLS public key. + keystore *BLSKeystore } type HandshakeMetadata struct { @@ -70,7 +92,7 @@ func NewRemoteNode(id RemoteNodeId, srv *Server, bc *Blockchain, cmgr *Connectio hyperSync bool, posValidator bool) *RemoteNode { return &RemoteNode{ id: id, - connectionStatus: RemoteNodeConnectionStatus_NotConnected, + connectionStatus: RemoteNodeStatus_NotConnected, handshakeMetadata: nil, srv: srv, bc: bc, @@ -89,7 +111,7 @@ func (rn *RemoteNode) SetPeer(peer *Peer) { } func (rn *RemoteNode) SetStatusConnected() { - rn.connectionStatus = RemoteNodeConnectionStatus_Connected + rn.connectionStatus = RemoteNodeStatus_Connected } func (rn *RemoteNode) GetPeer() *Peer { @@ -105,7 +127,7 @@ func (rn *RemoteNode) IsOutbound() bool { } func (rn *RemoteNode) IsConnected() bool { - return rn.connectionStatus == RemoteNodeConnectionStatus_Connected + return rn.connectionStatus == RemoteNodeStatus_Connected } func (rn *RemoteNode) IsValidator() bool { @@ -117,21 +139,21 @@ func (rn *RemoteNode) GetId() RemoteNodeId { } func (rn *RemoteNode) CreateOutboundConnection(netAddr *wire.NetAddress) { - if rn.connectionStatus != RemoteNodeConnectionStatus_NotConnected { + if rn.connectionStatus != RemoteNodeStatus_NotConnected { return } rn.cmgr.DialOutboundConnection(netAddr, rn.GetId().ToUint64()) - rn.connectionStatus = RemoteNodeConnectionStatus_Attempted + rn.connectionStatus = RemoteNodeStatus_Attempted } func (rn *RemoteNode) CreatePersistentOutboundConnection(netAddr *wire.NetAddress) { - if rn.connectionStatus != RemoteNodeConnectionStatus_NotConnected { + if rn.connectionStatus != RemoteNodeStatus_NotConnected { return } rn.cmgr.DialPersistentOutboundConnection(netAddr, rn.GetId().ToUint64()) - rn.connectionStatus = RemoteNodeConnectionStatus_Attempted + rn.connectionStatus = RemoteNodeStatus_Attempted } // ConnectInboundPeer connects a peer once a successful inbound connection has been established. @@ -159,16 +181,16 @@ func (rn *RemoteNode) ConnectOutboundPeer(conn net.Conn, na *wire.NetAddress, at func (rn *RemoteNode) Disconnect() { id := rn.GetId().ToUint64() switch rn.connectionStatus { - case RemoteNodeConnectionStatus_Attempted: + case RemoteNodeStatus_Attempted: rn.cmgr.CloseAttemptedConnection(id) - case RemoteNodeConnectionStatus_Connected: + case RemoteNodeStatus_Connected: rn.cmgr.CloseConnection(id) } - rn.connectionStatus = RemoteNodeConnectionStatus_Terminated + rn.connectionStatus = RemoteNodeStatus_Terminated } func (rn *RemoteNode) SendMessage(desoMsg DeSoMessage) { - if rn.connectionStatus != RemoteNodeConnectionStatus_Connected { + if rn.connectionStatus != RemoteNodeStatus_Connected { return }