25 lines
1.1 KiB
Markdown
25 lines
1.1 KiB
Markdown
# 0007. Verify a Merkle proof for every confirmed transaction
|
|||
|
|
|
||
|
|
- **Status:** Accepted
|
||
|
|
- **Area:** SPV
|
||
|
|
- **Recorded:** 2026-11-03 (retroactive: reconstructed from code, comments and changelog)
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
The indexing server is semi-trusted: it can lie about history. Without proof of inclusion it could fabricate a confirmed payment.
|
||
|
|
|
||
|
|
## Decision
|
||
|
|
|
||
|
|
Every confirmed transaction must come with a Merkle branch that `MerkleProof.Verify` checks against the merkle root of an anchored header (0006). The txid, position and branch are taken from the server, the root only from a verified header. A mismatch fails the sync with `SpvVerificationException`; unconfirmed transactions are shown as such and are never spendable.
|
||
|
|
|
||
|
|
## Consequences
|
||
|
|
|
||
|
|
- A malicious server cannot fabricate a confirmed transaction with a valid proof.
|
||
|
|
- Cost: one proof request per confirmed transaction, mitigated by caching verified state (0013) and progressive verification (0008).
|
||
|
|
- Script execution and double-spend detection are not covered; see `SECURITY.md`.
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- `src/Core/Spv/MerkleProof.cs`
|
||
|
|
- `src/Core/Spv/WalletSynchronizer.cs`
|
||
|
|
- `SECURITY.md`
|