@@ -5,7 +5,10 @@ use crate::{
5
5
spk_iter:: BIP32_MAX_INDEX ,
6
6
DescriptorExt , DescriptorId , SpkIterator , SpkTxOutIndex ,
7
7
} ;
8
- use bitcoin:: { hashes:: Hash , Amount , OutPoint , Script , SignedAmount , Transaction , TxOut , Txid } ;
8
+ use alloc:: borrow:: ToOwned ;
9
+ use bitcoin:: {
10
+ hashes:: Hash , Amount , OutPoint , Script , ScriptBuf , SignedAmount , Transaction , TxOut , Txid ,
11
+ } ;
9
12
use core:: {
10
13
fmt:: Debug ,
11
14
ops:: { Bound , RangeBounds } ,
@@ -127,8 +130,8 @@ const DEFAULT_LOOKAHEAD: u32 = 25;
127
130
///
128
131
/// # Change sets
129
132
///
130
- /// Methods that can update the last revealed index or add keychains will return [`super:: ChangeSet`] to report
131
- /// these changes. This can be persisted for future recovery.
133
+ /// Methods that can update the last revealed index or add keychains will return [`ChangeSet`] to
134
+ /// report these changes. This can be persisted for future recovery.
132
135
///
133
136
/// ## Synopsis
134
137
///
@@ -235,31 +238,35 @@ impl<K> Default for KeychainTxOutIndex<K> {
235
238
}
236
239
237
240
impl < K : Clone + Ord + Debug > Indexer for KeychainTxOutIndex < K > {
238
- type ChangeSet = super :: ChangeSet < K > ;
241
+ type ChangeSet = ChangeSet < K > ;
239
242
240
243
fn index_txout ( & mut self , outpoint : OutPoint , txout : & TxOut ) -> Self :: ChangeSet {
241
244
match self . inner . scan_txout ( outpoint, txout) . cloned ( ) {
242
245
Some ( ( descriptor_id, index) ) => {
243
246
// We want to reveal spks for descriptors that aren't tracked by any keychain, and
244
247
// so we call reveal with descriptor_id
245
- let ( _, changeset) = self . reveal_to_target_with_id ( descriptor_id, index)
246
- . expect ( "descriptors are added in a monotone manner, there cannot be a descriptor id with no corresponding descriptor" ) ;
248
+ let desc = self
249
+ . descriptor_ids_to_descriptors
250
+ . get ( & descriptor_id)
251
+ . cloned ( )
252
+ . expect ( "descriptors are added monotonically, scanned txout descriptor ids must have associated descriptors" ) ;
253
+ let ( _, changeset) = self . reveal_to_target_with_descriptor ( desc, index) ;
247
254
changeset
248
255
}
249
- None => super :: ChangeSet :: default ( ) ,
256
+ None => ChangeSet :: default ( ) ,
250
257
}
251
258
}
252
259
253
260
fn index_tx ( & mut self , tx : & bitcoin:: Transaction ) -> Self :: ChangeSet {
254
- let mut changeset = super :: ChangeSet :: < K > :: default ( ) ;
261
+ let mut changeset = ChangeSet :: < K > :: default ( ) ;
255
262
for ( op, txout) in tx. output . iter ( ) . enumerate ( ) {
256
263
changeset. append ( self . index_txout ( OutPoint :: new ( tx. txid ( ) , op as u32 ) , txout) ) ;
257
264
}
258
265
changeset
259
266
}
260
267
261
268
fn initial_changeset ( & self ) -> Self :: ChangeSet {
262
- super :: ChangeSet {
269
+ ChangeSet {
263
270
keychains_added : self
264
271
. keychains ( )
265
272
. map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) )
@@ -485,8 +492,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
485
492
& mut self ,
486
493
keychain : K ,
487
494
descriptor : Descriptor < DescriptorPublicKey > ,
488
- ) -> super :: ChangeSet < K > {
489
- let mut changeset = super :: ChangeSet :: < K > :: default ( ) ;
495
+ ) -> ChangeSet < K > {
496
+ let mut changeset = ChangeSet :: < K > :: default ( ) ;
490
497
let desc_id = descriptor. descriptor_id ( ) ;
491
498
492
499
let old_desc_id = self
@@ -708,24 +715,40 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
708
715
. descriptor_ids_to_descriptors
709
716
. get ( descriptor_id)
710
717
. expect ( "descriptor id cannot be associated with keychain without descriptor" ) ;
711
- let last_index = self . last_revealed . get ( descriptor_id) . cloned ( ) ;
718
+ Some ( self . next_index_with_descriptor ( descriptor) )
719
+ }
720
+
721
+ /// Get the next derivation index of given `descriptor`. The next derivation index is the index
722
+ /// after the last revealed index.
723
+ ///
724
+ /// The second field of the returned tuple represents whether the next derivation index is new.
725
+ /// There are two scenarios where the next derivation index is reused (not new):
726
+ ///
727
+ /// 1. The keychain's descriptor has no wildcard, and a script has already been revealed.
728
+ /// 2. The number of revealed scripts has already reached 2^31 (refer to BIP-32).
729
+ ///
730
+ /// Not checking the second field of the tuple may result in address reuse.
731
+ fn next_index_with_descriptor (
732
+ & self ,
733
+ descriptor : & Descriptor < DescriptorPublicKey > ,
734
+ ) -> ( u32 , bool ) {
735
+ let desc_id = descriptor. descriptor_id ( ) ;
712
736
713
- // we can only get the next index if the wildcard exists.
737
+ // we can only get the next index if the wildcard exists
714
738
let has_wildcard = descriptor. has_wildcard ( ) ;
739
+ let last_index = self . last_revealed . get ( & desc_id) . cloned ( ) ;
715
740
716
- Some ( match last_index {
717
- // if there is no index, next_index is always 0.
741
+ match last_index {
742
+ // if there is no index, next_index is always 0
718
743
None => ( 0 , true ) ,
719
- // descriptors without wildcards can only have one index.
744
+ // descriptors without wildcards can only have one index
720
745
Some ( _) if !has_wildcard => ( 0 , false ) ,
721
- // derivation index must be < 2^31 (BIP-32).
722
- Some ( index) if index > BIP32_MAX_INDEX => {
723
- unreachable ! ( "index is out of bounds" )
724
- }
746
+ // derivation index must be < 2^31 (BIP-32)
747
+ Some ( index) if index > BIP32_MAX_INDEX => unreachable ! ( "index out of bounds" ) ,
725
748
Some ( index) if index == BIP32_MAX_INDEX => ( index, false ) ,
726
- // get the next derivation index.
749
+ // get the next derivation index
727
750
Some ( index) => ( index + 1 , true ) ,
728
- } )
751
+ }
729
752
}
730
753
731
754
/// Get the last derivation index that is revealed for each keychain.
@@ -754,17 +777,16 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
754
777
keychains : & BTreeMap < K , u32 > ,
755
778
) -> (
756
779
BTreeMap < K , SpkIterator < Descriptor < DescriptorPublicKey > > > ,
757
- super :: ChangeSet < K > ,
780
+ ChangeSet < K > ,
758
781
) {
759
- let mut changeset = super :: ChangeSet :: default ( ) ;
782
+ let mut changeset = ChangeSet :: default ( ) ;
760
783
let mut spks = BTreeMap :: new ( ) ;
761
784
762
785
for ( keychain, & index) in keychains {
763
- if let Some ( ( new_spks, new_changeset) ) = self . reveal_to_target ( keychain, index) {
764
- if !new_changeset. is_empty ( ) {
765
- spks. insert ( keychain. clone ( ) , new_spks) ;
766
- changeset. append ( new_changeset. clone ( ) ) ;
767
- }
786
+ let ( new_spks, new_changeset) = self . reveal_to_target ( keychain, index) ;
787
+ if let Some ( new_spks) = new_spks {
788
+ changeset. append ( new_changeset) ;
789
+ spks. insert ( keychain. clone ( ) , new_spks) ;
768
790
}
769
791
}
770
792
@@ -777,18 +799,12 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
777
799
/// Refer to the `reveal_to_target` documentation for more.
778
800
///
779
801
/// Returns None if the provided `descriptor_id` doesn't correspond to a tracked descriptor.
780
- fn reveal_to_target_with_id (
802
+ fn reveal_to_target_with_descriptor (
781
803
& mut self ,
782
- descriptor_id : DescriptorId ,
804
+ descriptor : Descriptor < DescriptorPublicKey > ,
783
805
target_index : u32 ,
784
- ) -> Option < (
785
- SpkIterator < Descriptor < DescriptorPublicKey > > ,
786
- super :: ChangeSet < K > ,
787
- ) > {
788
- let descriptor = self
789
- . descriptor_ids_to_descriptors
790
- . get ( & descriptor_id) ?
791
- . clone ( ) ;
806
+ ) -> ( SpkIterator < Descriptor < DescriptorPublicKey > > , ChangeSet < K > ) {
807
+ let descriptor_id = descriptor. descriptor_id ( ) ;
792
808
let has_wildcard = descriptor. has_wildcard ( ) ;
793
809
794
810
let target_index = if has_wildcard { target_index } else { 0 } ;
@@ -801,10 +817,10 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
801
817
802
818
// If the target_index is already revealed, we are done
803
819
if next_reveal_index > target_index {
804
- return Some ( (
820
+ return (
805
821
SpkIterator :: new_with_range ( descriptor, next_reveal_index..next_reveal_index) ,
806
- super :: ChangeSet :: default ( ) ,
807
- ) ) ;
822
+ ChangeSet :: default ( ) ,
823
+ ) ;
808
824
}
809
825
810
826
// We range over the indexes that are not stored and insert their spks in the index.
@@ -822,13 +838,13 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
822
838
823
839
let _old_index = self . last_revealed . insert ( descriptor_id, target_index) ;
824
840
debug_assert ! ( _old_index < Some ( target_index) ) ;
825
- Some ( (
841
+ (
826
842
SpkIterator :: new_with_range ( descriptor, next_reveal_index..target_index + 1 ) ,
827
- super :: ChangeSet {
843
+ ChangeSet {
828
844
keychains_added : BTreeMap :: new ( ) ,
829
845
last_revealed : core:: iter:: once ( ( descriptor_id, target_index) ) . collect ( ) ,
830
846
} ,
831
- ) )
847
+ )
832
848
}
833
849
834
850
/// Reveals script pubkeys of the `keychain`'s descriptor **up to and including** the
@@ -839,76 +855,94 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
839
855
/// reveal up to the last possible index.
840
856
///
841
857
/// This returns an iterator of newly revealed indices (alongside their scripts) and a
842
- /// [`super:: ChangeSet`], which reports updates to the latest revealed index. If no new script
843
- /// pubkeys are revealed, then both of these will be empty.
858
+ /// [`ChangeSet`], which reports updates to the latest revealed index. If no new script pubkeys
859
+ /// are revealed, then both of these will be empty.
844
860
///
845
861
/// Returns None if the provided `keychain` doesn't exist.
846
862
pub fn reveal_to_target (
847
863
& mut self ,
848
864
keychain : & K ,
849
865
target_index : u32 ,
850
- ) -> Option < (
851
- SpkIterator < Descriptor < DescriptorPublicKey > > ,
852
- super :: ChangeSet < K > ,
853
- ) > {
854
- let descriptor_id = self . keychains_to_descriptor_ids . get ( keychain) ?;
855
- self . reveal_to_target_with_id ( * descriptor_id, target_index)
866
+ ) -> (
867
+ Option < SpkIterator < Descriptor < DescriptorPublicKey > > > ,
868
+ ChangeSet < K > ,
869
+ ) {
870
+ let descriptor_id = match self . keychains_to_descriptor_ids . get ( keychain) {
871
+ Some ( desc_id) => desc_id,
872
+ None => return ( None , ChangeSet :: default ( ) ) ,
873
+ } ;
874
+ let desc = self
875
+ . descriptor_ids_to_descriptors
876
+ . get ( descriptor_id)
877
+ . cloned ( )
878
+ . expect ( "descriptors are added monotonically, scanned txout descriptor ids must have associated descriptors" ) ;
879
+ let ( spk_iter, changeset) = self . reveal_to_target_with_descriptor ( desc, target_index) ;
880
+ ( Some ( spk_iter) , changeset)
856
881
}
857
882
858
883
/// Attempts to reveal the next script pubkey for `keychain`.
859
884
///
860
- /// Returns the derivation index of the revealed script pubkey, the revealed script pubkey and a
861
- /// [`super:: ChangeSet`] which represents changes in the last revealed index ( if any).
862
- /// Returns None if the provided keychain doesn't exist .
885
+ /// Returns the next revealed script pubkey (alongside it's derivation index), and a
886
+ /// [`ChangeSet`]. The next revealed script pubkey is `None` if the provided `keychain` has no
887
+ /// associated descriptor .
863
888
///
864
- /// When a new script cannot be revealed, we return the last revealed script and an empty
865
- /// [`super::ChangeSet`]. There are two scenarios when a new script pubkey cannot be derived:
889
+ /// When the descriptor has no more script pubkeys to reveal, the last revealed script and an
890
+ /// empty [`ChangeSet`] is returned. There are 3 scenarios in which a descriptor can no longer
891
+ /// derive scripts:
866
892
///
867
893
/// 1. The descriptor has no wildcard and already has one script revealed.
868
894
/// 2. The descriptor has already revealed scripts up to the numeric bound.
869
895
/// 3. There is no descriptor associated with the given keychain.
870
- pub fn reveal_next_spk (
871
- & mut self ,
872
- keychain : & K ,
873
- ) -> Option < ( ( u32 , & Script ) , super :: ChangeSet < K > ) > {
874
- let descriptor_id = self . keychains_to_descriptor_ids . get ( keychain) . cloned ( ) ?;
875
- let ( next_index, _) = self . next_index ( keychain) . expect ( "We know keychain exists" ) ;
876
- let changeset = self
877
- . reveal_to_target ( keychain, next_index)
878
- . expect ( "We know keychain exists" )
879
- . 1 ;
880
- let script = self
881
- . inner
882
- . spk_at_index ( & ( descriptor_id, next_index) )
883
- . expect ( "script must already be stored" ) ;
884
- Some ( ( ( next_index, script) , changeset) )
896
+ pub fn reveal_next_spk ( & mut self , keychain : & K ) -> ( Option < ( u32 , ScriptBuf ) > , ChangeSet < K > ) {
897
+ let descriptor_id = match self . keychains_to_descriptor_ids . get ( keychain) {
898
+ Some ( & desc_id) => desc_id,
899
+ None => {
900
+ return ( None , Default :: default ( ) ) ;
901
+ }
902
+ } ;
903
+ let descriptor = self
904
+ . descriptor_ids_to_descriptors
905
+ . get ( & descriptor_id)
906
+ . expect ( "descriptor id cannot be associated with keychain without descriptor" ) ;
907
+ let ( next_index, _) = self . next_index_with_descriptor ( descriptor) ;
908
+ let ( mut new_spks, changeset) =
909
+ self . reveal_to_target_with_descriptor ( descriptor. clone ( ) , next_index) ;
910
+ let revealed_spk = new_spks. next ( ) . unwrap_or_else ( || {
911
+ // if we have exhausted all derivation indicies, the returned `next_index` is reused
912
+ // and will not be included in `new_spks` (refer to `next_index_with_descriptor` docs)
913
+ let spk = self
914
+ . inner
915
+ . spk_at_index ( & ( descriptor_id, next_index) )
916
+ . expect ( "script must already be stored" )
917
+ . to_owned ( ) ;
918
+ ( next_index, spk)
919
+ } ) ;
920
+ debug_assert_eq ! ( new_spks. next( ) , None , "must only reveal one spk" ) ;
921
+ ( Some ( revealed_spk) , changeset)
885
922
}
886
923
887
- /// Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest
888
- /// index that has not been used yet .
924
+ /// Gets the next unused script pubkey in the keychain. I.e. the script pubkey with the lowest
925
+ /// derivation index that has not been used (no associated transaction outputs) .
889
926
///
890
- /// This will derive and reveal a new script pubkey if no more unused script pubkeys exist.
927
+ /// Returns the unused script pubkey (alongside it's derivation index), and a [`ChangeSet`].
928
+ /// The returned script pubkey will be `None` if the provided `keychain` has no associated
929
+ /// descriptor.
891
930
///
892
- /// If the descriptor has no wildcard and already has a used script pubkey or if a descriptor
893
- /// has used all scripts up to the derivation bounds, then the last derived script pubkey will be
894
- /// returned.
931
+ /// This will derive and reveal a new script pubkey if no more unused script pubkeys exists
932
+ /// (refer to [`reveal_next_spk`](Self::reveal_next_spk)).
895
933
///
896
- /// Returns None if the provided keychain doesn't exist.
897
- pub fn next_unused_spk (
898
- & mut self ,
899
- keychain : & K ,
900
- ) -> Option < ( ( u32 , & Script ) , super :: ChangeSet < K > ) > {
901
- let need_new = self . unused_keychain_spks ( keychain) . next ( ) . is_none ( ) ;
902
- // this rather strange branch is needed because of some lifetime issues
903
- if need_new {
904
- self . reveal_next_spk ( keychain)
934
+ /// If the descriptor has no wildcard and already has a used script pubkey or if a descriptor
935
+ /// has used all scripts up to the derivation bounds, then the last derived script pubkey will
936
+ /// be returned.
937
+ pub fn next_unused_spk ( & mut self , keychain : & K ) -> ( Option < ( u32 , ScriptBuf ) > , ChangeSet < K > ) {
938
+ let next_unused_spk = self
939
+ . unused_keychain_spks ( keychain)
940
+ . next ( )
941
+ . map ( |( i, spk) | ( i, spk. to_owned ( ) ) ) ;
942
+ if next_unused_spk. is_some ( ) {
943
+ ( next_unused_spk, Default :: default ( ) )
905
944
} else {
906
- Some ( (
907
- self . unused_keychain_spks ( keychain)
908
- . next ( )
909
- . expect ( "we already know next exists" ) ,
910
- super :: ChangeSet :: default ( ) ,
911
- ) )
945
+ self . reveal_next_spk ( keychain)
912
946
}
913
947
}
914
948
@@ -986,7 +1020,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
986
1020
/// - Adds new descriptors introduced
987
1021
/// - If a descriptor is introduced for a keychain that already had a descriptor, overwrites
988
1022
/// the old descriptor
989
- pub fn apply_changeset ( & mut self , changeset : super :: ChangeSet < K > ) {
1023
+ pub fn apply_changeset ( & mut self , changeset : ChangeSet < K > ) {
990
1024
let ChangeSet {
991
1025
keychains_added,
992
1026
last_revealed,
0 commit comments