@@ -1107,3 +1107,70 @@ impl<K: Clone + Ord + core::fmt::Debug> FullScanRequestBuilderExt<K> for FullSca
1107
1107
self
1108
1108
}
1109
1109
}
1110
+
1111
+ #[ cfg( test) ]
1112
+ mod test {
1113
+ use super :: * ;
1114
+
1115
+ use bdk_testenv:: utils:: DESCRIPTORS ;
1116
+ use bitcoin:: secp256k1:: Secp256k1 ;
1117
+ use miniscript:: Descriptor ;
1118
+
1119
+ // Test that `KeychainTxOutIndex` uses the spk cache.
1120
+ // And the indexed spks are as expected.
1121
+ #[ test]
1122
+ fn test_spk_cache ( ) {
1123
+ let lookahead = 10 ;
1124
+ let use_cache = true ;
1125
+ let mut index = KeychainTxOutIndex :: new ( lookahead, use_cache) ;
1126
+ let s = DESCRIPTORS [ 0 ] ;
1127
+
1128
+ let desc = Descriptor :: parse_descriptor ( & Secp256k1 :: new ( ) , s)
1129
+ . unwrap ( )
1130
+ . 0 ;
1131
+
1132
+ let did = desc. descriptor_id ( ) ;
1133
+
1134
+ let reveal_to = 2 ;
1135
+ let end_index = reveal_to + lookahead;
1136
+
1137
+ let _ = index. insert_descriptor ( 0i32 , desc. clone ( ) ) ;
1138
+ assert_eq ! ( index. spk_cache. get( & did) . unwrap( ) . len( ) as u32 , lookahead) ;
1139
+ assert_eq ! ( index. next_index( 0 ) , Some ( ( 0 , true ) ) ) ;
1140
+
1141
+ // Now reveal some scripts
1142
+ for _ in 0 ..=reveal_to {
1143
+ let _ = index. reveal_next_spk ( 0 ) . unwrap ( ) ;
1144
+ }
1145
+ assert_eq ! ( index. last_revealed_index( 0 ) , Some ( reveal_to) ) ;
1146
+
1147
+ let spk_cache = & index. spk_cache ;
1148
+ assert ! ( !spk_cache. is_empty( ) ) ;
1149
+
1150
+ for ( & did, cached_spks) in spk_cache {
1151
+ assert_eq ! ( did, desc. descriptor_id( ) ) ;
1152
+ for ( & i, cached_spk) in cached_spks {
1153
+ // Cached spk matches derived
1154
+ let exp_spk = desc. at_derivation_index ( i) . unwrap ( ) . script_pubkey ( ) ;
1155
+ assert_eq ! ( & exp_spk, cached_spk) ;
1156
+ // Also matches the inner index
1157
+ assert_eq ! ( index. spk_at_index( 0 , i) , Some ( cached_spk. clone( ) ) ) ;
1158
+ }
1159
+ }
1160
+
1161
+ let init_cs = index. initial_changeset ( ) ;
1162
+ assert_eq ! (
1163
+ init_cs. spk_cache. get( & did) . unwrap( ) . len( ) as u32 ,
1164
+ end_index + 1
1165
+ ) ;
1166
+
1167
+ // Now test load from changeset
1168
+ let recovered =
1169
+ KeychainTxOutIndex :: < & str > :: from_changeset ( lookahead, use_cache, init_cs. clone ( ) ) ;
1170
+ assert_eq ! ( & recovered. spk_cache, spk_cache) ;
1171
+
1172
+ // The cache is optional at load time
1173
+ let index = KeychainTxOutIndex :: < i32 > :: from_changeset ( lookahead, false , init_cs) ;
1174
+ assert ! ( index. spk_cache. is_empty( ) ) ;
1175
+ }
1176
+ }
0 commit comments