Skip to content

Commit 741f2ae

Browse files
committed
test: persist indexed script pubkeys
1 parent db25555 commit 741f2ae

File tree

1 file changed

+68
-9
lines changed

1 file changed

+68
-9
lines changed

wallet/tests/wallet.rs

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
use std::collections::BTreeMap;
12
use std::path::Path;
23
use std::str::FromStr;
34
use std::sync::Arc;
45

56
use anyhow::Context;
67
use assert_matches::assert_matches;
7-
use bdk_chain::{BlockId, CanonicalizationParams, ChainPosition, ConfirmationBlockTime};
8+
use bdk_chain::{
9+
keychain_txout::DEFAULT_LOOKAHEAD, BlockId, CanonicalizationParams, ChainPosition,
10+
ConfirmationBlockTime, DescriptorExt,
11+
};
812
use bdk_wallet::coin_selection::{self, LargestFirstCoinSelection};
913
use bdk_wallet::descriptor::{calc_checksum, DescriptorError, IntoWalletDescriptor};
1014
use bdk_wallet::error::CreateTxError;
@@ -70,6 +74,7 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
7074
let mut db = create_db(&file_path)?;
7175
let mut wallet = Wallet::create(external_desc, internal_desc)
7276
.network(Network::Testnet)
77+
.use_spk_cache(true)
7378
.create_wallet(&mut db)?;
7479
wallet.reveal_next_address(KeychainKind::External);
7580

@@ -79,13 +84,6 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
7984
};
8085

8186
// recover wallet
82-
{
83-
let mut db = open_db(&file_path).context("failed to recover db")?;
84-
let _ = Wallet::load()
85-
.check_network(Network::Testnet)
86-
.load_wallet(&mut db)?
87-
.expect("wallet must exist");
88-
}
8987
{
9088
let mut db = open_db(&file_path).context("failed to recover db")?;
9189
let wallet = Wallet::load()
@@ -113,6 +111,67 @@ fn wallet_is_persisted() -> anyhow::Result<()> {
113111
.0
114112
);
115113
}
114+
// Test SPK cache
115+
{
116+
let mut db = open_db(&file_path).context("failed to recover db")?;
117+
let mut wallet = Wallet::load()
118+
.check_network(Network::Testnet)
119+
.use_spk_cache(true)
120+
.load_wallet(&mut db)?
121+
.expect("wallet must exist");
122+
123+
let external_did = wallet
124+
.public_descriptor(KeychainKind::External)
125+
.descriptor_id();
126+
let internal_did = wallet
127+
.public_descriptor(KeychainKind::Internal)
128+
.descriptor_id();
129+
130+
assert!(wallet.staged().is_none());
131+
132+
let _addr = wallet.reveal_next_address(KeychainKind::External);
133+
let cs = wallet.staged().expect("we should have staged a changeset");
134+
assert!(!cs.indexer.spk_cache.is_empty(), "failed to cache spks");
135+
assert_eq!(cs.indexer.spk_cache.len(), 2, "we persisted two keychains");
136+
let spk_cache: &BTreeMap<u32, ScriptBuf> =
137+
cs.indexer.spk_cache.get(&external_did).unwrap();
138+
assert_eq!(spk_cache.len() as u32, 1 + 1 + DEFAULT_LOOKAHEAD);
139+
assert_eq!(spk_cache.keys().last(), Some(&26));
140+
let spk_cache = cs.indexer.spk_cache.get(&internal_did).unwrap();
141+
assert_eq!(spk_cache.len() as u32, DEFAULT_LOOKAHEAD);
142+
assert_eq!(spk_cache.keys().last(), Some(&24));
143+
// Clear the stage
144+
let _ = wallet.take_staged();
145+
let _addr = wallet.reveal_next_address(KeychainKind::Internal);
146+
let cs = wallet.staged().unwrap();
147+
assert_eq!(cs.indexer.spk_cache.len(), 1);
148+
let spk_cache = cs.indexer.spk_cache.get(&internal_did).unwrap();
149+
assert_eq!(spk_cache.len(), 1);
150+
assert_eq!(spk_cache.keys().next(), Some(&25));
151+
}
152+
// SPK cache requires load params
153+
{
154+
let mut db = open_db(&file_path).context("failed to recover db")?;
155+
let mut wallet = Wallet::load()
156+
.check_network(Network::Testnet)
157+
// .use_spk_cache(false)
158+
.load_wallet(&mut db)?
159+
.expect("wallet must exist");
160+
161+
let internal_did = wallet
162+
.public_descriptor(KeychainKind::Internal)
163+
.descriptor_id();
164+
165+
assert!(wallet.staged().is_none());
166+
167+
let _addr = wallet.reveal_next_address(KeychainKind::Internal);
168+
let cs = wallet.staged().expect("we should have staged a changeset");
169+
assert_eq!(cs.indexer.last_revealed.get(&internal_did), Some(&0));
170+
assert!(
171+
cs.indexer.spk_cache.is_empty(),
172+
"we didn't set `use_spk_cache`"
173+
);
174+
}
116175

117176
Ok(())
118177
}
@@ -4406,7 +4465,7 @@ fn test_taproot_load_descriptor_duplicated_keys() {
44064465
#[test]
44074466
#[cfg(debug_assertions)]
44084467
#[should_panic(
4409-
expected = "replenish lookahead: must not have existing spk: keychain=Internal, lookahead=25, next_store_index=0, next_reveal_index=0"
4468+
expected = "replenish lookahead: must not have existing spk: keychain=Internal, lookahead=25, next_index=0"
44104469
)]
44114470
fn test_keychains_with_overlapping_spks() {
44124471
// this can happen if a non-wildcard descriptor keychain derives an spk that a

0 commit comments

Comments
 (0)