Files
PalladiumWallet/docs/adr/0006-spv-checkpoint-anchoring-without-pow.md
T
davide b292590cdc docs: add docs-as-code process and one ADR per feature
docs/docs-as-code.md defines the workflow; docs/adr holds 31 ADRs
(retroactive, reconstructed from code and changelog) with a template and
index. docs/check-docs.sh validates ADR structure, index, cited code
paths, relative links and CLAUDE.md/AGENTS.md sync.
2026-11-03 09:45:51 +01:00

1.4 KiB

0006. Anchor headers to hardcoded checkpoints and skip PoW validation

  • Status: Accepted
  • Area: SPV
  • Recorded: 2026-11-03 (retroactive: reconstructed from code, comments and changelog)

Context

Palladium uses LWMA difficulty with 2-minute blocks. An SPV client cannot recompute LWMA without the full header history, and NBitcoin assumes Bitcoin's retargeting rules, so checking proof of work client-side would either be wrong or require downloading every header.

Decision

Set SkipPowValidation = true in the profile and anchor trust to hardcoded checkpoints instead. For each header used in a Merkle proof, WalletSynchronizer.AnchorToCheckpointAsync downloads the intervening headers, verifies the prev-hash chain back to the nearest checkpoint at or below that height, and requires that checkpoint's hash to match exactly. Mainnet carries a checkpoint every 20,000 blocks.

Consequences

  • A server cannot feed an alternative history below the newest checkpoint.
  • Headers above the newest checkpoint are linked but their work is not verified; this is an accepted limitation documented in SECURITY.md.
  • Testnet/regtest have no checkpoints, so headers there are trusted at face value.
  • Checkpoints must be extended with releases; a wrong checkpoint would reject every honest server.

References

  • src/Core/Spv/WalletSynchronizer.cs
  • src/Core/Spv/BlockHeaderInfo.cs
  • src/Core/Chain/ChainProfiles.cs
  • SECURITY.md