/**
 * V3 Gossip Protocol Consensus
 * Eventually consistent consensus for large-scale distributed systems
 */
import { EventEmitter } from 'events';
import type { ConsensusTransport } from './transport.js';
import { ConsensusProposal, ConsensusVote, ConsensusResult, ConsensusConfig } from '../types.js';
export interface GossipMessage {
    id: string;
    type: 'proposal' | 'vote' | 'state' | 'ack';
    senderId: string;
    version: number;
    payload: unknown;
    timestamp: Date;
    ttl: number;
    hops: number;
    path: string[];
}
/**
 * Bounded set that evicts oldest entries when capacity is reached.
 * Uses Map insertion-order for O(1) FIFO eviction. (PERF-01)
 */
export declare class BoundedSet<T> {
    private map;
    private readonly maxSize;
    constructor(maxSize: number);
    has(value: T): boolean;
    add(value: T): void;
    get size(): number;
    clear(): void;
}
export interface GossipNode {
    id: string;
    state: Map<string, unknown>;
    version: number;
    neighbors: Set<string>;
    seenMessages: BoundedSet<string>;
    lastSync: Date;
}
export interface GossipConfig extends Partial<ConsensusConfig> {
    fanout?: number;
    gossipIntervalMs?: number;
    maxHops?: number;
    convergenceThreshold?: number;
    /**
     * ADR-095 G2 — optional pluggable transport. When set, gossip messages
     * to neighbors actually go over it (signed if the transport has a
     * keypair) and inbound gossip is routed back into the merge logic.
     * When unset, behavior is unchanged: the legacy in-process path mutates
     * the local `nodes` map directly (single-process).
     */
    transport?: ConsensusTransport;
}
export declare class GossipConsensus extends EventEmitter {
    private config;
    private node;
    private nodes;
    private proposals;
    private messageQueue;
    private gossipInterval?;
    private proposalCounter;
    private readonly transport?;
    constructor(nodeId: string, config?: GossipConfig);
    /**
     * ADR-095 G2 — route an inbound transport message into the gossip merge
     * logic. The transport handles signature verification (if enabled). We
     * dedupe by message id (the BoundedSet `seenMessages`) and process it as
     * though it arrived from a neighbor.
     */
    private handleInboundGossipMessage;
    initialize(): Promise<void>;
    shutdown(): Promise<void>;
    addNode(nodeId: string): void;
    removeNode(nodeId: string): void;
    addNeighbor(nodeId: string): void;
    removeNeighbor(nodeId: string): void;
    propose(value: unknown): Promise<ConsensusProposal>;
    vote(proposalId: string, vote: ConsensusVote): Promise<void>;
    awaitConsensus(proposalId: string): Promise<ConsensusResult>;
    private startGossipLoop;
    private gossipRound;
    private selectRandomNeighbors;
    private sendToNeighbor;
    private processReceivedMessage;
    private handleProposalMessage;
    private handleVoteMessage;
    private handleStateMessage;
    private queueMessage;
    private checkConvergence;
    private createResult;
    getConvergence(proposalId: string): number;
    getVersion(): number;
    getNeighborCount(): number;
    getSeenMessageCount(): number;
    getQueueDepth(): number;
    antiEntropy(): Promise<void>;
}
export declare function createGossipConsensus(nodeId: string, config?: GossipConfig): GossipConsensus;
//# sourceMappingURL=gossip.d.ts.map