Skip to content

Commit 5f9c03f

Browse files
committed
Persist cached SPKs on wallet creation
1 parent 4e202c8 commit 5f9c03f

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

src/wallet/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2838,7 +2838,7 @@ fn make_indexed_graph(
28382838
use_spk_cache: bool,
28392839
) -> Result<IndexedTxGraph<ConfirmationBlockTime, KeychainTxOutIndex<KeychainKind>>, DescriptorError>
28402840
{
2841-
let (indexed_graph, changeset) = IndexedTxGraph::from_changeset(
2841+
let (mut indexed_graph, changeset) = IndexedTxGraph::from_changeset(
28422842
chain::indexed_tx_graph::ChangeSet {
28432843
tx_graph: tx_graph_changeset,
28442844
indexer: indexer_changeset,
@@ -2880,8 +2880,19 @@ fn make_indexed_graph(
28802880
Ok(idx)
28812881
},
28822882
)?;
2883+
// `insert_descriptor` stages any newly derived lookahead SPKs inside the indexer, but
2884+
// `IndexedTxGraph::from_changeset` only returns reindexing changes. Flush the stage here so
2885+
// wallet creation persists the initial SPK cache.
2886+
let mut initial_indexer_changeset = indexed_graph
2887+
.index
2888+
.index_txout(OutPoint::null(), &TxOut::NULL);
2889+
initial_indexer_changeset
2890+
.spk_cache
2891+
.retain(|_, spks| !spks.is_empty());
2892+
28832893
stage.tx_graph.merge(changeset.tx_graph);
28842894
stage.indexer.merge(changeset.indexer);
2895+
stage.indexer.merge(initial_indexer_changeset);
28852896
Ok(indexed_graph)
28862897
}
28872898

tests/persisted_wallet.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,39 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
101101
let (external_desc, internal_desc) = get_test_tr_single_sig_xprv_and_change_desc();
102102

103103
// create new wallet
104-
let wallet_spk_index = {
104+
{
105105
let mut db = create_db(&file_path)?;
106-
let mut wallet = Wallet::create(external_desc, internal_desc)
106+
let wallet = Wallet::create(external_desc, internal_desc)
107107
.network(Network::Testnet)
108108
.use_spk_cache(true)
109109
.create_wallet(&mut db)?;
110110

111-
wallet.reveal_next_address(KeychainKind::External);
111+
assert!(
112+
wallet.staged().is_none(),
113+
"persisted wallet creation should write the initial changeset"
114+
);
115+
}
116+
117+
// reload immediately to ensure the initial cached SPKs were persisted at creation time
118+
let wallet_spk_index = {
119+
let mut db = open_db(&file_path)?;
120+
let mut wallet = Wallet::load()
121+
.check_network(Network::Testnet)
122+
.use_spk_cache(true)
123+
.load_wallet(&mut db)?
124+
.expect("wallet must exist");
125+
126+
assert!(wallet.staged().is_none());
127+
128+
let revealed_external_addr = wallet.reveal_next_address(KeychainKind::External);
112129

113130
check_cache_cs(
114131
&staged_cache(&wallet),
115-
[
116-
(KeychainKind::External, 0..DEFAULT_LOOKAHEAD + 1),
117-
(KeychainKind::Internal, 0..DEFAULT_LOOKAHEAD),
118-
],
119-
"cache cs must return initial set + the external index that was just derived",
132+
[(
133+
KeychainKind::External,
134+
[revealed_external_addr.index + DEFAULT_LOOKAHEAD],
135+
)],
136+
"initial cached SPKs should already be persisted at wallet creation",
120137
);
121138

122139
// persist new wallet changes

0 commit comments

Comments
 (0)