Skip to content

fix(chain): return false for untracked indices in SpkTxOutIndex::is_used - #2445

Open
bhuvan-somisetty wants to merge 1 commit into
bitcoindevkit:masterfrom
bhuvan-somisetty:fix-spk-is-used-untracked
Open

bhuvan-somisetty wants to merge 1 commit into
bitcoindevkit:masterfrom
bhuvan-somisetty:fix-spk-is-used-untracked

Conversation

@bhuvan-somisetty

@bhuvan-somisetty bhuvan-somisetty commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes an issue where SpkTxOutIndex::is_used returns true for an index that was never tracked or added to the index (e.g. on an empty index or querying an unrevealed keychain derivation index in KeychainTxOutIndex::is_used).

is_used previously checked !self.unused.contains(index). Because self.unused only tracks indices that were explicitly added to the index, any index that has never been tracked is absent from self.unused, causing is_used to evaluate to true.

This PR updates SpkTxOutIndex::is_used to verify self.spks.contains_key(index) && !self.unused.contains(index), matching the guard already present in unmark_used. It also adds documentation and unit tests for both SpkTxOutIndex and KeychainTxOutIndex.

Closes #2444.

Notes to the reviewers

  • SpkTxOutIndex::unmark_used already explicitly checks if !self.spks.contains_key(index) { return false; }. Applying self.spks.contains_key(index) to is_used brings full symmetry between both methods and preserves the invariant that untracked indices are not considered used.
  • Added unit tests in test_spk_txout_index.rs and test_keychain_txout_index.rs.

Changelog notice

  • Changed SpkTxOutIndex::is_used and KeychainTxOutIndex::is_used to return false for untracked or unrevealed indices instead of true.

Checklists

All Submissions:

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.30%. Comparing base (02b7b12) to head (1cf692d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2445      +/-   ##
==========================================
+ Coverage   83.25%   83.30%   +0.04%     
==========================================
  Files          31       31              
  Lines        6236     6236              
  Branches      293      294       +1     
==========================================
+ Hits         5192     5195       +3     
+ Misses        976      973       -3     
  Partials       68       68              
Flag Coverage Δ
rust 83.30% <100.00%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@yahia008 yahia008 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK aa79e14

I'm fairly new to this codebase, so take this as a tested-locally comment and not a
maintainer review.

I checked out the PR and ran the new tests; both pass, along with the existing
test_keychain_txout_index suite. The new check matches the guard already in unmark_used,
and the only caller of SpkTxOutIndex::is_used I found in the repo is
KeychainTxOutIndex::is_used, which forwards to it.

A few small things, not blocking:

  • The MSRV job fails during dependency resolution on 1.85, and that doesn't look related
    to this change. Master has updated the MSRV script since this branch was cut, so would a
    rebase help?
  • The KeychainTxOutIndex::is_used doc could say "an unrevealed index" instead of "the spk
    under keychain and index".
  • Since unknown indices now return false where they used to return true, would
    "Changed" fit the changelog better than "Fixed"?

@bhuvan-somisetty
bhuvan-somisetty force-pushed the fix-spk-is-used-untracked branch from aa79e14 to d1821e1 Compare November 2, 2026 11:07
@bhuvan-somisetty

Copy link
Copy Markdown
Contributor Author

Thanks! Rebased on master, which should fix MSRV, updated the doc wording, and switched the changelog to "Changed".

Previously, `SpkTxOutIndex::is_used` checked `!self.unused.contains(index)`.
Because `self.unused` only tracks indices that were explicitly added to the index,
any untracked index was absent from `self.unused`, causing `is_used` to evaluate
to `true`.

Check `self.spks.contains_key(index)` in `is_used` to ensure untracked indices
return `false`. Also update documentation and add unit tests for `SpkTxOutIndex`
and `KeychainTxOutIndex`.

Closes bitcoindevkit#2444

Signed-off-by: bhuvan-somisetty <somisettybhuvan5@gmail.com>
@bhuvan-somisetty
bhuvan-somisetty force-pushed the fix-spk-is-used-untracked branch from d1821e1 to 1cf692d Compare November 5, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

SpkTxOutIndex::is_used returns true for untracked indices

2 participants