Class GossipProtocol

java.lang.Object
com.privatechain.network.gossip.GossipProtocol
All Implemented Interfaces:
BlockchainEventListener

public final class GossipProtocol extends Object implements BlockchainEventListener
Propagates submitted transactions to a random subset of connected peers via epidemic gossip.

GossipProtocol implements BlockchainEventListener so that it can be registered on the event bus. When a BlockchainEvent.TransactionSubmittedEvent is published, this class selects ceil(log₂(n)) random peers and forwards the transaction to each (FR-NET-03).

Fan-out size

Using ⌈log₂(n)⌉ as the fan-out grows slowly with the network size, providing sub-logarithmic propagation time with high probability (analogous to Ethereum's discovery). For a 25-peer network this yields 5 initial recipients.

Loop prevention

The originating sender ID is stamped into the message envelope. Recipients compare the senderId against their own node ID and against a bounded set of recently seen transaction IDs to avoid re-gossiping what they just received. The seen-set is maintained in a fixed-size LinkedHashMap LRU cache.

Direct gossip API

In addition to the event-listener path, callers (e.g., NodeServer) can call gossip(Transaction, String) directly when processing an inbound transaction message that needs to be forwarded.

Thread safety

All public methods are safe for concurrent use. The seen-set is synchronized; peer selection uses an immutable snapshot of the peer list; gossip sends are dispatched to a cached thread pool.

Since:
1.0.0
See Also:
  • Constructor Details

    • GossipProtocol

      public GossipProtocol(String localNodeId, PeerManager peerManager, NodeClient nodeClient, MessageCodec codec)
      Constructs a GossipProtocol with the required dependencies.
      Parameters:
      localNodeId - this node's stable logical identifier (non-null, non-blank)
      peerManager - provides connected peers for gossip target selection (non-null)
      nodeClient - outbound connection factory (non-null)
      codec - message encoder (non-null)
      Throws:
      NullPointerException - if any parameter is null
      IllegalArgumentException - if localNodeId is blank
  • Method Details

    • computeFanOut

      public static int computeFanOut(int n)
      Computes ⌈log₂(n)⌉ — the gossip fan-out for n eligible peers.

      Always returns at least 1, even if n == 1.

      Parameters:
      n - number of eligible peers (≥ 1)
      Returns:
      fan-out count (≥ 1)
    • onEvent

      public void onEvent(BlockchainEvent event)
      Reacts to blockchain events.

      Only BlockchainEvent.TransactionSubmittedEvent instances trigger gossip; all other events are ignored. The originating sender is assumed to be the local node when called via the event bus (i.e., the transaction was submitted locally).

      Specified by:
      onEvent in interface BlockchainEventListener
      Parameters:
      event - the blockchain event to process (non-null)
    • gossip

      public void gossip(Transaction transaction, String originSenderId)
      Gossips a transaction to ⌈log₂(n)⌉ randomly selected connected peers.

      This method is idempotent for duplicate transaction IDs — if the same transaction has been gossiped recently it is silently skipped. The originator (originSenderId) is excluded from the recipient set so that a transaction is never echoed back to the node that sent it.

      Parameters:
      transaction - the transaction to propagate (non-null)
      originSenderId - the node ID that originally submitted this transaction; excluded from the recipient set (non-null, non-blank)
      Throws:
      NullPointerException - if transaction or originSenderId is null
      IllegalArgumentException - if originSenderId is blank
    • shutdown

      public void shutdown()
      Shuts down the gossip thread pool.

      In-flight sends that have already been submitted will be interrupted. New gossip calls submitted after this point are rejected.