bitcoindevkit / bitcoindevkit/bdk

`SpkTxOutIndex::insert_spk` leaves stale mappings when reusing an index

Open Beginner friendly
#2,279 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
1.1k
Forks
483
Avg merge
20d 3h
Merged PRs (30d)
3

Description

**Describe the bug**

Calling `SpkTxOutIndex::insert_spk` with an existing index and a different script replaces the forward mapping but keeps the old reverse mapping. Both scripts then resolve to the same index, so `scan_txout` can associate an output with an index whose `spk_at_index` returns a different script.

This issue was found by AI.

**To Reproduce**

Reproduced on `master` (`acc06e53220960caa89efd5984d7b43914640dd4`). Add this test to `crates/chain/tests/test_spk_txout_index.rs`:

```rust
#[test]
fn reusing_index_preserves_script_lookup_consistency() {
use bdk_chain::{bitcoin::ScriptBuf, spk_txout::SpkTxOutIndex};

let old_script = ScriptBuf::from_bytes(vec![0x51]);
let new_script = ScriptBuf::from_bytes(vec![0x52]);
let mut index = SpkTxOutIndex::::default();

index.insert_spk(0, old_script.clone());
index.insert_spk(0, new_script.clone());

for script in [old_script, new_script] {
if let Some(script_index) = index.index_of_spk(&script) {
assert_eq!(index.spk_at_index(script_index), Some(script));
}
}
}
```

Run `cargo test -p bdk_chain --test test_spk_txout_index reusing_index_preserves_script_lookup_consistency`. The assertion fails: the old script resolves to index `0`, but that index now returns the new script.

**Expected behavior**

Script-to-index and index-to-script lookups should remain consistent when an index is reused, including for output indexing.

Contributor guide

Open the contributing guide

Research direction

Start by reading SpkTxOutIndex::insert_spk and the related lookup methods, then run the reproducer in crates/chain/tests/test_spk_txout_index.rs. Ensure reusing an index keeps script-to-index and index-to-script lookups consistent, including scan_txout behavior, and verify with the named cargo test.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.