@@ -517,9 +517,18 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
517
517
1
518
518
} ;
519
519
520
- let cached_spk_iter = core :: iter :: from_fn ( {
520
+ let derive_spk = {
521
521
let secp = Secp256k1 :: verification_only ( ) ;
522
522
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 ( {
523
532
let spk_cache = self . spk_cache . entry ( did) . or_default ( ) ;
524
533
let _i = & mut next_index;
525
534
move || -> Option < Indexed < ScriptBuf > > {
@@ -530,15 +539,13 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
530
539
* _i = spk_i. saturating_add ( 1 ) ;
531
540
532
541
if let Some ( spk) = spk_cache. get ( & spk_i) {
542
+ debug_assert_eq ! ( spk, & derive_spk( spk_i) , "cached spk must equal derived" ) ;
533
543
return Some ( ( spk_i, spk. clone ( ) ) ) ;
534
544
}
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) ;
539
546
derived_spks. extend ( core:: iter:: once ( ( spk_i, spk. clone ( ) ) ) ) ;
540
547
spk_cache. insert ( spk_i, spk. clone ( ) ) ;
541
- Some ( ( spk_i, spk. clone ( ) ) )
548
+ Some ( ( spk_i, spk) )
542
549
}
543
550
} ) ;
544
551
@@ -947,7 +954,7 @@ pub struct ChangeSet {
947
954
/// Contains for each descriptor_id the last revealed index of derivation
948
955
pub last_revealed : BTreeMap < DescriptorId , u32 > ,
949
956
950
- /// Spk cache .
957
+ /// Cache of previously derived script pubkeys .
951
958
#[ cfg_attr( feature = "serde" , serde( default ) ) ]
952
959
pub spk_cache : BTreeMap < DescriptorId , BTreeMap < u32 , ScriptBuf > > ,
953
960
}
@@ -972,7 +979,14 @@ impl Merge for ChangeSet {
972
979
}
973
980
974
981
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) ;
976
990
}
977
991
}
978
992
0 commit comments