{"record":{"id":"4e8b12e656809e98","repo":"datahaven-xyz/datahaven","slug":"invalidfinalizedheadergap","errorCode":"InvalidFinalizedHeaderGap","errorMessage":"InvalidFinalizedHeaderGap","messagePattern":"InvalidFinalizedHeaderGap","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"operator/pallets/ethereum-client/src/lib.rs","lineNumber":363,"sourceCode":"                )\n            }\n\n            // Verify update is relevant.\n            let update_attested_period = compute_period(update.attested_header.slot);\n            let update_finalized_period = compute_period(update.finalized_header.slot);\n            let update_has_next_sync_committee = !<NextSyncCommittee<T>>::exists()\n                && (update.next_sync_committee_update.is_some()\n                    && update_attested_period == store_period);\n            ensure!(\n                update.attested_header.slot > latest_finalized_state.slot\n                    || update_has_next_sync_committee,\n                Error::<T>::IrrelevantUpdate\n            );\n\n            // Verify the finalized header gap between the current finalized header and new imported\n            // header is not larger than the sync committee period, otherwise we cannot do\n            // ancestry proofs for execution headers in the gap.\n            ensure!(\n                latest_finalized_state\n                    .slot\n                    .saturating_add(config::SLOTS_PER_HISTORICAL_ROOT as u64)\n                    >= update.finalized_header.slot,\n                Error::<T>::InvalidFinalizedHeaderGap\n            );\n\n            let fork_versions = T::ForkVersions::get();\n            let finalized_root_gindex = Self::finalized_root_gindex_at_slot(\n                update.attested_header.slot,\n                fork_versions.clone(),\n            );\n            // Verify that the `finality_branch`, if present, confirms `finalized_header` to match\n            // the finalized checkpoint root saved in the state of `attested_header`.\n            let finalized_block_root: H256 = update\n                .finalized_header\n                .hash_tree_root()\n                .map_err(|_| Error::<T>::HeaderHashTreeRootFailed)?;","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/datahaven-xyz/datahaven/blob/edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec/operator/pallets/ethereum-client/src/lib.rs#L345-L381","documentation":"The gap between the current finalized header slot and the new finalized header slot exceeds `SLOTS_PER_HISTORICAL_ROOT` (8192 slots, one sync committee period). The light client caches block roots to serve ancestry proofs for execution headers; a gap larger than one historical-roots window would break those proofs, so `verify_update` rejects it.","triggerScenarios":"Submitting an update where `latest_finalized_state.slot + 8192 < update.finalized_header.slot` — the client's finalized header is more than one full sync committee period behind the update being imported.","commonSituations":"Relayer downtime longer than one period followed by submission of only the latest update; client halted (see the Halted kill-switch) while the chain kept finalizing; operator skips intermediate updates.","solutions":["Import updates incrementally so the finalized header advances at most one period at a time.","Re-bootstrap from a fresh trusted checkpoint if the gap cannot be covered by intermediate updates.","Keep the relayer monitored so finalized-header gaps never exceed one period.","Combine with period checks: the SkippedSyncCommitteePeriod guard usually fires first; fix the same root cause."],"exampleFix":"// before\n submit(latest_update); // finalized_header.slot far ahead\n// after\n while client.latest_finalized_slot() + 8192 < latest_update.finalized_header.slot {\n     submit(next_intermediate_update())?;\n }\n submit(latest_update);","handlingStrategy":"validation","validationCode":"if (latestFinalizedSlot + 8192 < update.finalizedHeader.slot) throw new Error('finalized header gap too large');","typeGuard":null,"tryCatchPattern":"try { await submit(update); } catch (e) { if (e.includes('InvalidFinalizedHeaderGap')) { submitIntermediateUpdates(); } else throw e; }","preventionTips":["Advance the client at most one period per import","Watch finalized-slot lag metrics","Re-bootstrap after long outages"],"tags":["substrate","beacon-consensus","ancestry-proof","gap"],"backgroundTag":"invalid-state-transition","analyzedSha":"edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec","analyzedAt":"2026-09-13T19:19:32.206Z","contentChangedAt":"2026-09-13T19:19:32.206Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}