/**
 * V3 Byzantine Fault Tolerant Consensus
 * PBFT-style consensus for handling malicious or faulty nodes
 */
import { EventEmitter } from 'events';
import { ConsensusProposal, ConsensusVote, ConsensusResult, ConsensusConfig } from '../types.js';
import type { ConsensusTransport } from './transport.js';
export type ByzantinePhase = 'pre-prepare' | 'prepare' | 'commit' | 'reply';
export interface ByzantineMessage {
    type: ByzantinePhase;
    viewNumber: number;
    sequenceNumber: number;
    digest: string;
    senderId: string;
    timestamp: Date;
    payload?: unknown;
    signature?: string;
}
export interface ByzantineNode {
    id: string;
    isPrimary: boolean;
    viewNumber: number;
    sequenceNumber: number;
    preparedMessages: Map<string, ByzantineMessage[]>;
    committedMessages: Map<string, ByzantineMessage[]>;
}
export interface ByzantineConfig extends Partial<ConsensusConfig> {
    maxFaultyNodes?: number;
    viewChangeTimeoutMs?: number;
    /**
     * ADR-095 G2 — optional pluggable transport. When set, PBFT messages
     * (pre-prepare/prepare/commit) go over it (and are signed if the
     * transport has a keypair) instead of being `emit`ted into the void.
     * When unset, behavior is unchanged: messages are emitted as
     * `message.broadcast` / `message.sent` events for an external wiring
     * layer to relay (the legacy single-process path).
     */
    transport?: ConsensusTransport;
}
export declare class ByzantineConsensus extends EventEmitter {
    private config;
    private node;
    private nodes;
    private proposals;
    private messageLog;
    private proposalCounter;
    private viewChangeTimeout?;
    private readonly transport?;
    constructor(nodeId: string, config?: ByzantineConfig);
    /**
     * ADR-095 G2 — dispatch an inbound transport message to the right PBFT
     * handler. The transport has already verified the signature (if signing
     * is on); here we only need to demux by type and reconstruct the
     * ByzantineMessage shape the handlers expect.
     */
    private handleInboundMessage;
    initialize(): Promise<void>;
    shutdown(): Promise<void>;
    addNode(nodeId: string, isPrimary?: boolean): void;
    removeNode(nodeId: string): void;
    /**
     * ADR-095 G2 — BFT fault tolerance f, derived from the *actual* cluster
     * size unless explicitly capped via config.maxFaultyNodes. PBFT needs
     * n ≥ 3f+1, so f = floor((n-1)/3) where n = self + known peers. The
     * config value (if set) acts as an upper bound — never exceed what the
     * operator declared the cluster can tolerate.
     */
    private byzantineF;
    electPrimary(): string;
    propose(value: unknown): Promise<ConsensusProposal>;
    vote(proposalId: string, vote: ConsensusVote): Promise<void>;
    awaitConsensus(proposalId: string): Promise<ConsensusResult>;
    handlePrePrepare(message: ByzantineMessage): Promise<void>;
    handlePrepare(message: ByzantineMessage): Promise<void>;
    handleCommit(message: ByzantineMessage): Promise<void>;
    initiateViewChange(): Promise<void>;
    private broadcastMessage;
    private computeDigest;
    private createResult;
    isPrimary(): boolean;
    getViewNumber(): number;
    getSequenceNumber(): number;
    getPreparedCount(): number;
    getCommittedCount(): number;
    getMaxFaultyNodes(): number;
    canTolerate(faultyCount: number): boolean;
}
export declare function createByzantineConsensus(nodeId: string, config?: ByzantineConfig): ByzantineConsensus;
//# sourceMappingURL=byzantine.d.ts.map