type ChunkProbeFailureReason = "rpc_error" | "decode_error" | "metadata_error"; type ChunkProbeResult = { cid: string; present: false; } | { cid: string; present: true; block: number; index: number; } | { cid: string; present: null; failureReason: ChunkProbeFailureReason; }; interface ChainProbeOptions { client: any; batchSize?: number; atFinalized?: boolean; } declare class ChainProbeMetadataError extends Error { constructor(msg: string); } declare class ChainProbeCrossValidationError extends Error { constructor(msg: string); } /** Exported for unit testing. */ declare function _decodeStorageValue(hex: string | null | undefined): { block: number; index: number; } | null; declare function probeChunks(cids: string[], options: ChainProbeOptions): Promise; /** * Splits cids that are missing at finalised head into two buckets, using a * best-block probe result for each cid: * - `lagging`: present at best-block. GRANDPA just hasn't caught up yet * (#1049) — these were never lost and must NEVER be re-uploaded. * - `reallyMissing`: absent at best-block too (or the best-block probe * itself failed, `present === null`) — genuinely dropped, or we * couldn't determine presence at all. Either way, re-upload is the * safe default: treating an indeterminate result as "lagging" risks * silently skipping a chunk that's actually gone. * * Pure function — no chain I/O — so it's directly unit-testable against a * mocked ChunkProbeResult array without a client. */ declare function classifyFinalityGap(missingAtFinalized: string[], bestBlockResults: ChunkProbeResult[]): { reallyMissing: string[]; lagging: string[]; }; /** * Composite, chain-touching version of classifyFinalityGap (#1049): probes * `missingAtFinalized` at best-block, retries once on an indeterminate * result (present === null), then classifies. Any caller that finds cids * missing at finalised head should route through this — not re-implement * the probe/retry/classify sequence inline — so the "finalised-head absence * is not proof of loss" policy stays consistent everywhere it's checked * (the GRANDPA finality-check phase and the pre-setContenthash root * re-check both use it). */ declare function probeFinalityGap(missingAtFinalized: string[], options: ChainProbeOptions): Promise<{ reallyMissing: string[]; lagging: string[]; }>; /** * Best (non-finalised) block height, via `chain_getHeader`. Used by the * initial chunk-upload retry loop (#1051) to detect a frozen chain — no new * blocks since the last check — so it can wait instead of resubmitting into * a stall (which just manufactures same-nonce collisions once the chain * resumes). Returns `null` on any RPC failure or malformed response; callers * must treat `null` as "can't tell" and fail open (proceed as if live) * rather than blocking forever on a single bad peer. */ declare function getBestBlockNumber(client: any): Promise; /** Reset session-level caches. Used in tests only. */ declare function _resetProbeSession(): void; /** Pre-set metadataChecked so tests don't need a real metadata RPC mock. Used in tests only. */ declare function _bypassMetadataCheckForTest(): void; export { ChainProbeCrossValidationError, ChainProbeMetadataError, type ChainProbeOptions, type ChunkProbeFailureReason, type ChunkProbeResult, _bypassMetadataCheckForTest, _decodeStorageValue, _resetProbeSession, classifyFinalityGap, getBestBlockNumber, probeChunks, probeFinalityGap };