Class PeerManager

java.lang.Object
com.privatechain.network.peer.PeerManager
All Implemented Interfaces:
PeerManagerLifecycle

public final class PeerManager extends Object implements PeerManagerLifecycle
Manages the lifecycle of peer connections in the private blockchain P2P network.

Responsibilities (FR-NET-01):

Milestone 8 wiring (T-066)

Every successful connect(Peer) publishes a BlockchainEvent.PeerConnectedEvent and every disconnect(String, String) publishes a BlockchainEvent.PeerDisconnectedEvent asynchronously.

Design note

This class coordinates lifecycle — actual TCP I/O is delegated to NodeServer and NodeClient in the transport layer.

Since:
1.0.0
See Also:
  • Field Details

    • HEARTBEAT_INTERVAL_SECONDS

      public static final int HEARTBEAT_INTERVAL_SECONDS
      How often the heartbeat task checks peer liveness (seconds).
      See Also:
    • PEER_TIMEOUT_SECONDS

      public static final int PEER_TIMEOUT_SECONDS
      Silence duration before a peer is considered unresponsive (seconds).
      See Also:
  • Constructor Details

    • PeerManager

      public PeerManager(PeerStore peerStore, BlockchainEventBus eventBus, int maxPeers)
      Constructs a PeerManager with all required dependencies.
      Parameters:
      peerStore - the backing peer store (non-null)
      eventBus - event bus for publishing peer lifecycle events (non-null)
      maxPeers - maximum simultaneous peer connections (≥ 1)
      Throws:
      NullPointerException - if peerStore or eventBus is null
      IllegalArgumentException - if maxPeers < 1
  • Method Details

    • start

      public void start()
      Starts the peer manager and schedules the periodic heartbeat/pruning task.

      This method is idempotent; calling it while already running is a no-op.

      Specified by:
      start in interface PeerManagerLifecycle
    • stop

      public void stop()
      Stops the peer manager, disconnects all peers, and shuts down the heartbeat scheduler.
      Specified by:
      stop in interface PeerManagerLifecycle
    • getConnectedPeerCount

      public int getConnectedPeerCount()
      Returns the number of currently connected peers.
      Specified by:
      getConnectedPeerCount in interface PeerManagerLifecycle
      Returns:
      connected peer count (≥ 0)
    • connect

      public boolean connect(Peer peer)
      Registers a peer as connected and publishes a BlockchainEvent.PeerConnectedEvent (T-066).

      If the peer is already connected, or if the max peer count is reached, this method returns false and takes no action. On success the peer is persisted to the PeerStore with a fresh lastSeen timestamp via PeerStore.put(Peer).

      Parameters:
      peer - the peer that has established a connection (non-null)
      Returns:
      true if the peer was newly added; false otherwise
      Throws:
      NullPointerException - if peer is null
    • disconnect

      public void disconnect(String nodeId, String reason)
      Marks a peer as disconnected and publishes a BlockchainEvent.PeerDisconnectedEvent (T-066).

      The peer remains in the PeerStore for potential reconnection. Only its entry in the connected-nodes set is removed.

      Parameters:
      nodeId - the node ID of the peer to disconnect (non-null, non-blank)
      reason - human-readable reason; may be null
      Throws:
      NullPointerException - if nodeId is null
      IllegalArgumentException - if nodeId is blank
    • disconnectAll

      public void disconnectAll(String reason)
      Disconnects all currently connected peers with the given reason.
      Parameters:
      reason - human-readable reason; may be null
    • recordHeartbeat

      public void recordHeartbeat(String nodeId)
      Records a successful heartbeat for the given peer, refreshing its lastSeen timestamp in the PeerStore.

      Called by the transport layer whenever a ping/pong or any valid inbound message is received from the peer.

      Parameters:
      nodeId - the node ID of the peer to refresh (non-null, non-blank)
      Throws:
      NullPointerException - if nodeId is null
      IllegalArgumentException - if nodeId is blank
    • getConnectedPeers

      public List<Peer> getConnectedPeers()
      Returns a snapshot list of all currently connected Peer instances.
      Returns:
      unmodifiable list of connected peers; never null
    • isConnected

      public boolean isConnected(String nodeId)
      Returns true if the peer with the given node ID is currently connected.
      Parameters:
      nodeId - the node ID to check (non-null)
      Returns:
      true if connected
      Throws:
      NullPointerException - if nodeId is null
    • getPeerStore

      public PeerStore getPeerStore()
      Returns the backing PeerStore for direct peer-level operations.
      Returns:
      non-null PeerStore
    • toString

      public String toString()
      Returns a human-readable summary of the peer manager state.
      Overrides:
      toString in class Object
      Returns:
      string representation