bitcoindevkit / bitcoindevkit/bdk
`SpkTxOutIndex::insert_spk` leaves stale mappings when reusing an index
- 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
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