Skip to content

Commit d761265

Browse files
committed
feat(chain): KeychainTxOutIndex: Debug build checks
* 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.
1 parent 76875e7 commit d761265

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

crates/chain/src/indexer/keychain_txout.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -517,9 +517,18 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
517517
1
518518
};
519519

520-
let cached_spk_iter = core::iter::from_fn({
520+
let derive_spk = {
521521
let secp = Secp256k1::verification_only();
522522
let _desc = &descriptor;
523+
move |spk_i: u32| -> ScriptBuf {
524+
_desc
525+
.derived_descriptor(&secp, spk_i)
526+
.expect("The descriptor cannot have hardened derivation")
527+
.script_pubkey()
528+
}
529+
};
530+
531+
let cached_spk_iter = core::iter::from_fn({
523532
let spk_cache = self.spk_cache.entry(did).or_default();
524533
let _i = &mut next_index;
525534
move || -> Option<Indexed<ScriptBuf>> {
@@ -530,15 +539,13 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
530539
*_i = spk_i.saturating_add(1);
531540

532541
if let Some(spk) = spk_cache.get(&spk_i) {
542+
debug_assert_eq!(spk, &derive_spk(spk_i), "cached spk must equal derived");
533543
return Some((spk_i, spk.clone()));
534544
}
535-
let spk = _desc
536-
.derived_descriptor(&secp, spk_i)
537-
.expect("The descriptor cannot have hardened derivation")
538-
.script_pubkey();
545+
let spk = derive_spk(spk_i);
539546
derived_spks.extend(core::iter::once((spk_i, spk.clone())));
540547
spk_cache.insert(spk_i, spk.clone());
541-
Some((spk_i, spk.clone()))
548+
Some((spk_i, spk))
542549
}
543550
});
544551

@@ -947,7 +954,7 @@ pub struct ChangeSet {
947954
/// Contains for each descriptor_id the last revealed index of derivation
948955
pub last_revealed: BTreeMap<DescriptorId, u32>,
949956

950-
/// Spk cache.
957+
/// Cache of previously derived script pubkeys.
951958
#[cfg_attr(feature = "serde", serde(default))]
952959
pub spk_cache: BTreeMap<DescriptorId, BTreeMap<u32, ScriptBuf>>,
953960
}
@@ -972,7 +979,14 @@ impl Merge for ChangeSet {
972979
}
973980

974981
for (did, spks) in other.spk_cache {
975-
self.spk_cache.entry(did).or_default().extend(spks);
982+
let orig_spks = self.spk_cache.entry(did).or_default();
983+
debug_assert!(
984+
orig_spks
985+
.iter()
986+
.all(|(i, orig_spk)| spks.get(i).map_or(true, |spk| spk == orig_spk)),
987+
"spk of the same descriptor-id and derivation index must not be different"
988+
);
989+
orig_spks.extend(spks);
976990
}
977991
}
978992

0 commit comments

Comments
 (0)