UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

150 lines 6.83 kB
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 { PeerSyncMeta } from "../network/peers/peersData.js"; import { PeerIdStr } from "../util/peerId.js"; import { SyncOptions } from "./options.js"; /** * BlockInputSync is a class that handles ReqResp to find blocks and data related to a specific blockRoot. The * blockRoot may have been found via object gossip, or the API. Gossip objects that can trigger a search are block, * blobs, columns, attestations, etc. In the case of blocks and data this is generally during the current slot but * can also be for items that are received late but are not fully verified and thus not in fork-choice (old blocks on * an unknown fork). It can also be triggered via an attestation (or sync committee message or any other item that * gets gossiped) that references a blockRoot that is not in fork-choice. In rare (and realistically should not happen) * situations it can get triggered via the API when the validator attempts to publish a block, attestation, aggregate * and proof or a sync committee contribution that has unknown information included (parentRoot for instance). * * The goal of the class is to make sure that all information that is necessary for import into fork-choice is pulled * from peers so that the block and data can be processed, and thus the object that triggered the search can be * referenced and validated. * * The most common case for this search is a set of block/data that comes across gossip for the current slot, during * normal chain operation, but not everything was received before the gossip cutoff window happens so it is necessary * to pull remaining data via req/resp so that fork-choice can be updated prior to making an attestation for the * current slot. * * Event sources for old UnknownBlock * * - publishBlock * - gossipHandlers * - searchUnknownBlock * = produceSyncCommitteeContribution * = validateGossipFnRetryUnknownRoot * * submitPoolAttestationsV2 * * publishAggregateAndProofsV2 * = onPendingGossipsubMessage * * NetworkEvent.pendingGossipsubMessage * - onGossipsubMessage */ export declare class BlockInputSync { 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 pendingPayloads; private readonly knownBadBlocks; private readonly maxPendingBlocks; private subscribedToNetworkEvents; private peerBalancer; private rateLimitBackoffTimeout; 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 onUnknownBlockRoot; /** * Process an unknownBlockInput event and register the block in `pendingBlocks` Map. */ private onIncompleteBlockInput; private onUnknownEnvelopeBlockRoot; private onIncompletePayloadEnvelope; /** * Process an unknownBlockParent event and register the block in `pendingBlocks` Map. */ private onUnknownParent; private onBlockImported; private onPayloadImported; private addByRootHex; private addByBlockInput; private addByPayloadRootHex; private addByPayloadInput; private onPeerConnected; private onPeerDisconnected; /** * Post-gloas, a locally complete block can still be blocked on its parent's execution payload lineage. * Distinguish which dependency is missing so the scheduler can enqueue the right follow-up work. */ private getMissingBlockDependency; private advancePendingBlock; private toPendingPayloadInput; /** * Gather tip parent blocks with unknown parent and do a search for all of them */ private triggerUnknownBlockSearch; private scheduleRateLimitBackoffRetry; private clearRateLimitBackoffTimer; private downloadBlock; private processReadyBlock; private reconcilePayloadEnvelope; private downloadPayload; private processPayload; private fetchPayloadInput; private fetchExecutionPayloadEnvelope; private fetchPayloadColumns; private fetchBlockInput; /** * 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 removePendingPayloadAndDescendants; private removeAllDescendants; private getMaxDownloadAttempts; } /** * Class to track active byRoots requests and balance them across eligible peers. */ export declare class UnknownBlockPeerBalancer { readonly peersMeta: Map<PeerIdStr, PeerSyncMeta>; readonly activeRequests: Map<PeerIdStr, number>; readonly rateLimitedUntilByPeer: Map<PeerIdStr, number>; constructor(); /** Trigger on each peer re-status */ onPeerConnected(peerId: PeerIdStr, syncMeta: PeerSyncMeta): void; onPeerDisconnected(peerId: PeerIdStr): void; onRateLimited(peerId: PeerIdStr, rateLimitedUntilMs: number): void; getNextRateLimitRetryAt(pendingColumns?: Set<number>, excludedPeers?: Set<PeerIdStr>): number | null; /** * called from fetchBlockInput() where we only have block root and nothing else * excludedPeers are the peers that we requested already so we don't want to try again * pendingColumns is empty for prefulu, or the 1st time we we download a block by root */ bestPeerForPendingColumns(pendingColumns: Set<number>, excludedPeers: Set<PeerIdStr>): PeerSyncMeta | null; /** * Consumers don't need to call this method directly, it is called internally by bestPeer*() methods * make this public for testing */ onRequest(peerId: PeerIdStr): void; /** * Consumers should call this method when a request is completed for a peer. */ onRequestCompleted(peerId: PeerIdStr): void; getTotalActiveRequests(): number; private filterPeers; private peerHasPendingColumns; } //# sourceMappingURL=unknownBlock.d.ts.map