import { ChainForkConfig } from "@lodestar/config";
import { Logger } from "@lodestar/utils";
import { IBeaconChain } from "../chain/index.js";
import { Metrics } from "../metrics/index.js";
import { INetwork } from "../network/index.js";
import { SyncOptions } from "./options.js";
export declare class UnknownBlockSync {
    private readonly config;
    private readonly network;
    private readonly chain;
    private readonly logger;
    private readonly metrics;
    private readonly opts?;
    /**
     * block RootHex -> PendingBlock. To avoid finding same root at the same time
     */
    private readonly pendingBlocks;
    private readonly knownBadBlocks;
    private readonly proposerBoostSecWindow;
    private readonly maxPendingBlocks;
    private subscribedToNetworkEvents;
    private engineGetBlobsCache;
    private blockInputsRetryTrackerCache;
    constructor(config: ChainForkConfig, network: INetwork, chain: IBeaconChain, logger: Logger, metrics: Metrics | null, opts?: SyncOptions | undefined);
    subscribeToNetwork(): void;
    unsubscribeFromNetwork(): void;
    close(): void;
    isSubscribedToNetwork(): boolean;
    /**
     * Process an unknownBlock event and register the block in `pendingBlocks` Map.
     */
    private onUnknownBlock;
    /**
     * Process an unknownBlockInput event and register the block in `pendingBlocks` Map.
     */
    private onUnknownBlockInput;
    /**
     * Process an unknownBlockParent event and register the block in `pendingBlocks` Map.
     */
    private onUnknownParent;
    /**
     * When a blockInput comes with  an unknown parent:
     * - add the block to pendingBlocks with status downloaded, blockRootHex as key. This is similar to
     * an `onUnknownBlock` event, but the blocks is downloaded.
     * - add the parent root to pendingBlocks with status pending, parentBlockRootHex as key. This is
     * the same to an `onUnknownBlock` event with parentBlockRootHex as root.
     */
    private addUnknownParent;
    private addUnknownBlock;
    /**
     * Gather tip parent blocks with unknown parent and do a search for all of them
     */
    private triggerUnknownBlockSearch;
    private downloadBlock;
    /**
     * Send block to the processor awaiting completition. If processed successfully, send all children to the processor.
     * On error, remove and downscore all descendants.
     */
    private processBlock;
    /**
     * Fetches the parent of a block by root from a set of shuffled peers.
     * Will attempt a max of `MAX_ATTEMPTS_PER_BLOCK` on different peers if connectPeers.length > MAX_ATTEMPTS_PER_BLOCK.
     * Also verifies the received block root + returns the peer that provided the block for future downscoring.
     */
    private fetchUnknownBlockRoot;
    /**
     * Fetches missing blobs for the blockinput, in future can also pull block is thats also missing
     * along with the blobs (i.e. only some blobs are available)
     */
    private fetchUnavailableBlockInput;
    /**
     * Gets all descendant blocks of `block` recursively from `pendingBlocks`.
     * Assumes that if a parent block does not exist or is not processable, all descendant blocks are bad too.
     * Downscore all peers that have referenced any of this bad blocks. May report peers multiple times if they have
     * referenced more than one bad block.
     */
    private removeAndDownscoreAllDescendants;
    private removeAllDescendants;
}
//# sourceMappingURL=unknownBlock.d.ts.map