Persist spks derived from KeychainTxOutIndex#1963
Merged
ValuedMammal merged 8 commits intobitcoindevkit:masterfrom May 27, 2025
Merged
Persist spks derived from KeychainTxOutIndex#1963ValuedMammal merged 8 commits intobitcoindevkit:masterfrom
KeychainTxOutIndex#1963ValuedMammal merged 8 commits intobitcoindevkit:masterfrom
Conversation
7afd8b6 to
c279c99
Compare
c279c99 to
d299dae
Compare
Thanks to @ValuedMammal for the suggestions
90b6813 to
76875e7
Compare
* When merging changesets, assert that spk of a given descriptor id & derivation index does not get changed. * When reading spk from cache, check the spk by deriving it.
fb838d9 to
d761265
Compare
This incentivies constructing `KeychainTxOutIndex` from a changeset before inserting descriptors (to make use of the spk cache).
9d97b29 to
4bc8cc0
Compare
Also added staging changes to `ChangeSet::spk_cache`. This way, we can avoid returning `ChangeSet`s for `apply_changeset` and `insert_descriptor`. * `KeychainTxOutIndex::new` now takes in an additional `use_spk_cache` parameter. * Fixed `reveal_to_target` method to actually return `None` if the keychain does not exist.
4bc8cc0 to
bbbc054
Compare
* `new` is now intended to construct a fresh indexed-tx-graph * `from_changeset` is added for constructing indexed-tx-graph from a previously persisted changeset * added `reindex` for calling after indexer mutations that require it * reintroduce `Default` impl
bbbc054 to
3126cd2
Compare
8fef7c7 to
603f133
Compare
3 tasks
ValuedMammal
requested changes
May 26, 2025
Do not reference last revealed table, in case none are revealed. Correct SQL column name.
Member
|
|
notmandatory
approved these changes
May 27, 2025
Member
notmandatory
left a comment
There was a problem hiding this comment.
ACK 62767f0
tested with bdk-cli with cache enabled and sqlite schema updated and new table is being populated.
| /// | ||
| /// let (graph, reindex_cs) = | ||
| /// IndexedTxGraph::from_changeset(persisted_changeset, move |idx_cs| -> anyhow::Result<_> { | ||
| /// // e.g. KeychainTxOutIndex needs descriptors that weren’t in its CS |
Collaborator
There was a problem hiding this comment.
// e.g. KeychainTxOutIndex needs descriptors that weren’t in its change set.|
|
||
| impl<K> KeychainTxOutIndex<K> { | ||
| /// Construct a [`KeychainTxOutIndex`] with the given `lookahead`. | ||
| /// Construct a [`KeychainTxOutIndex`] with the given `lookahead` and `use_spk_cache` boolean. |
Collaborator
There was a problem hiding this comment.
/// Construct a [`KeychainTxOutIndex`] with the given `lookahead` and `persist_spks` boolean.
| /// // Derive 20 future addresses per chain and persist + reload script pubkeys via ChangeSets: | ||
| /// let idx = KeychainTxOutIndex::<&'static str>::new(20, true); | ||
| /// | ||
| /// // Derive 10 future addresses per chain without persistence: |
| impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> { | ||
| /// Construct `KeychainTxOutIndex<K>` from the given `changeset`. | ||
| /// | ||
| /// Shorthand for called [`new`] and then [`apply_changeset`]. |
Collaborator
There was a problem hiding this comment.
Shorthand for "calling"...
| /// | ||
| /// It tracks: | ||
| /// 1. `last_revealed`: the highest derivation index revealed per descriptor. | ||
| /// 2. `spks`: the cache of derived script pubkeys to persist across runs. |
Collaborator
There was a problem hiding this comment.
/// 2. `spk_cache`: ...
ValuedMammal
added a commit
to ValuedMammal/bdk
that referenced
this pull request
May 30, 2025
This commit addresses some leftover comments from bitcoindevkit#1963.
ValuedMammal
added a commit
to ValuedMammal/bdk
that referenced
this pull request
Feb 10, 2026
`spk_cache_stage` was being used to hold newly derived SPKs before being transferred to the `ChangeSet`. As a result it became necessary to call `_empty_stage_into_changeset` whenever the internal state changed, requiring the developer to know which methods depended on the functionality, e.g. `scan_txout` and `reveal_next_spk`. Further, this altered the behavior of the `ChangeSet` in surprising ways. For example revealing 1 SPK might return additional scripts in the `ChangeSet` if they had previously been staged. The rationale in bitcoindevkit#1963 was to avoid returning a `ChangeSet` from `insert_descriptor`. We can do this by providing another method that returns a tuple of `(bool, ChangeSet)` so that descriptor insertion results in updating the `ChangeSet` directly. Any code using the original `insert_descriptor` can still access the `ChangeSet` using `initial_changeset` (which may include SPKs from other descriptors), or we can expose an accessor to get a reference to the `spk_cache`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #1960
Fixes #1953
Fixes #1964
Description
Users with large wallet and/or complex descriptors may experience slow startup of
KeychainTxOutIndex. This PR addresses this problem by providing the option to persist derived spks so that they no longer need to be re-derived on startup.The
IndexedTxGraphAPI has been changed for better ergonomics.Compared to #1960, this is a more longterm solution that does not depend on multi-threading logic.
Changelog notice
Checklists
All Submissions:
cargo +nightly fmtandcargo clippybefore committingNew Features: