import { MetaDBManager } from '../util/metaDBManager.ts'; import type { Block, BlockHeader } from '@ethereumjs/block'; import type { Hardfork } from '@ethereumjs/common'; import type { SnapFetcherDoneFlags } from '../sync/fetcher/types.ts'; import type { MetaDBManagerOptions } from '../util/metaDBManager.ts'; export type PutStatus = (typeof PutStatus)[keyof typeof PutStatus]; export declare const PutStatus: { readonly VALID: "VALID"; readonly INVALID: "INVALID"; }; type FillStatus = { status: PutStatus; height: bigint; hash: Uint8Array; validationError?: string; }; /** * Contiguous header chain segment that is backed by the database, * but may not be linked to the live chain. The skeleton downloader may produce * a new one of these every time it is restarted until the subchain grows large * enough to connect with a previous subchain. */ type SkeletonSubchain = { head: bigint; /** Block number of the newest header in the subchain */ tail: bigint; /** Block number of the oldest header in the subchain */ next: Uint8Array; /** Block hash of the next oldest header in the subchain */ }; /** * errSyncReorged is an internal helper error to signal that the head chain of * the current sync cycle was (partially) reorged, thus the skeleton syncer * should abort and restart with the new state. */ export declare const errSyncReorged: import("@ethereumjs/rlp").EthereumJSError<{ code: string; }>; /** * errReorgDenied is returned if an attempt is made to extend the beacon chain * with a new header, but it does not link up to the existing sync. */ export declare const errReorgDenied: import("@ethereumjs/rlp").EthereumJSError<{ code: string; }>; /** * errSyncMerged is an internal helper error to signal that the current sync * cycle merged with a previously aborted subchain, thus the skeleton syncer * should abort and restart with the new state. */ export declare const errSyncMerged: import("@ethereumjs/rlp").EthereumJSError<{ code: string; }>; export declare class Skeleton extends MetaDBManager { private _lock; private status; fillStatus: FillStatus | null; private started; /** Timestamp when the skeleton syncer was created */ private syncedchain; private pulled; /** Number of headers downloaded in this run */ private filling; /** Whether we are actively filling the canonical chain */ private lastfilledAt; private lastfilled; private lastexecutedAt; private lastexecuted; private lastfetchedAt; private lastfetched; private lastvalid; private lastFcuTime; private lastsyncedAt; private STATUS_LOG_INTERVAL; /** How often to log sync status (in ms) */ /** * safeBlock as indicated by engine api, set */ safeBlock?: Block; finalizedBlock?: Block; synchronized: boolean; private lastSynchronized; private lastSyncDate; constructor(opts: MetaDBManagerOptions); /** * Run a function after acquiring a lock. It is implied that we have already * initialized the module (or we are calling this from the init function, like * `_setCanonicalGenesisBlock`) * @param action - function to run after acquiring a lock * @hidden */ private runWithLock; open(): Promise; close(): Promise; reset(): Promise; /** * Returns true if the skeleton chain is linked to canonical */ private checkLinked; isLinked(): boolean; isStarted(): boolean; isLastAnnouncement(): Promise; /** * Try fast forwarding the chain head to the number */ private fastForwardHead; /** * processNewHead does the internal shuffling for a new head marker and either * accepts and integrates it into the skeleton or requests a reorg. Upon reorg, * the syncer will tear itself down and restart with a fresh head. It is simpler * to reconstruct the sync state than to mutate it. * * @returns true if the chain was reorged */ private processNewHead; /** * Announce and integrate a new head. * @params head - The block being attempted as a new head * @params force - Flag to indicate if this is just a check of worthiness or a actually new head * @params init - Flag this is the first time since the beacon sync start to perform additional tasks * @params reorgThrow - Flag to indicate if we would actually like to throw if there is a reorg * instead of just returning the boolean * * @returns True if the head (will) cause a reorg in the canonical skeleton subchain */ setHead(head: Block, force?: boolean, init?: boolean, reorgThrow?: boolean): Promise; /** * Updates if the skeleton/cl seems synced to the head * copied over from config, could be DRY-ied * @param option latest to update the sync state with */ updateSynchronizedState(latest?: BlockHeader | null): void; forkchoiceUpdate(headBlock: Block, { safeBlockHash, finalizedBlockHash, }?: { safeBlockHash?: Uint8Array; finalizedBlockHash?: Uint8Array; }): Promise<{ reorged: boolean; safeBlock?: Block; finalizedBlock?: Block; }>; setVmHead(snapStatus: { syncedHash: Uint8Array; syncedHeight: bigint; }): Promise; /** * Setup the skeleton to init sync with head * @params head - The block with which we want to init the skeleton head * @params reorgThrow - If we would like the function to throw instead of silently * return if there is reorg of the skeleton head * * @returns True if the skeleton was reorged trying to init else false */ initSync(head: Block, reorgThrow?: boolean): Promise; /** * Bounds returns the current head and tail tracked by the skeleton syncer. */ bounds(): SkeletonSubchain; headHash(): Promise; private trySubChainsMerge; /** * Writes skeleton blocks to the db by number * @returns number of blocks saved */ putBlocks(blocks: Block[], skipForwardFill?: boolean): Promise; private backStep; /** * fill the canonical chain from skeleton if there is only a small segment to fill */ blockingFillWithCutoff(cutoffLen: number): Promise; getUnfinalizedParentsForBackfill(maxItems: number): Promise; /** * lookup and try backfill if skeleton already has blocks previously filled */ tryTailBackfill(): Promise; /** * */ blockingTailBackfillWithCutoff(maxItems: number): Promise; /** * Inserts skeleton blocks into canonical chain and runs execution. */ fillCanonicalChain(skipUpdateEmit?: boolean): Promise; serialize({ hardfork, blockRLP, }: { hardfork: Hardfork | string; blockRLP: Uint8Array; }): Uint8Array; deserialize(rlp: Uint8Array): { hardfork: Hardfork | string; blockRLP: Uint8Array; }; /** * Writes a skeleton block to the db by number */ private putBlock; skeletonBlockRlpToBlock(skeletonBlockRlp: Uint8Array): Block; /** * Gets a block from the skeleton or canonical db by number. */ getBlock(number: bigint, onlyCanonical?: boolean): Promise; /** * Gets a skeleton block from the db by hash */ getBlockByHash(hash: Uint8Array, onlyCanonical?: boolean): Promise; getUnfinalizedBlock(hash: Uint8Array): Promise; /** * Deletes a skeleton block from the db by number */ deleteBlock(block: Block): Promise; /** * * TODO: complete the impl of pruning of blocks which got finalized and were non * canonical. canonical blocks anyway get deleted in deleteBlock */ pruneFinalizedNonCanonicalBlocks(): Promise; logSyncStatus(logPrefix: string, { forceShowInfo, lastStatus, vmexecution, fetching, snapsync, peers, }?: { forceShowInfo?: boolean; lastStatus?: string; vmexecution?: { running: boolean; started: boolean; }; fetching?: boolean; snapsync?: SnapFetcherDoneFlags; peers?: number | string; }): string; /** * Writes the {@link SkeletonStatus} to db */ private writeSyncStatus; /** * Reads the {@link SkeletonStatus} from db */ private getSyncStatus; /** * Encodes a {@link SkeletonStatus} to RLP for saving to the db */ private statusToRLP; /** * Decodes an RLP encoded {@link SkeletonStatus} */ private statusRLPtoObject; } export {}; //# sourceMappingURL=skeleton.d.ts.map