@@ -5,7 +5,10 @@ use crate::{
55 spk_iter:: BIP32_MAX_INDEX ,
66 DescriptorExt , DescriptorId , SpkIterator , SpkTxOutIndex ,
77} ;
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+ } ;
912use core:: {
1013 fmt:: Debug ,
1114 ops:: { Bound , RangeBounds } ,
@@ -127,8 +130,8 @@ const DEFAULT_LOOKAHEAD: u32 = 25;
127130///
128131/// # Change sets
129132///
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.
132135///
133136/// ## Synopsis
134137///
@@ -235,31 +238,35 @@ impl<K> Default for KeychainTxOutIndex<K> {
235238}
236239
237240impl < K : Clone + Ord + Debug > Indexer for KeychainTxOutIndex < K > {
238- type ChangeSet = super :: ChangeSet < K > ;
241+ type ChangeSet = ChangeSet < K > ;
239242
240243 fn index_txout ( & mut self , outpoint : OutPoint , txout : & TxOut ) -> Self :: ChangeSet {
241244 match self . inner . scan_txout ( outpoint, txout) . cloned ( ) {
242245 Some ( ( descriptor_id, index) ) => {
243246 // We want to reveal spks for descriptors that aren't tracked by any keychain, and
244247 // 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) ;
247254 changeset
248255 }
249- None => super :: ChangeSet :: default ( ) ,
256+ None => ChangeSet :: default ( ) ,
250257 }
251258 }
252259
253260 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 ( ) ;
255262 for ( op, txout) in tx. output . iter ( ) . enumerate ( ) {
256263 changeset. append ( self . index_txout ( OutPoint :: new ( tx. txid ( ) , op as u32 ) , txout) ) ;
257264 }
258265 changeset
259266 }
260267
261268 fn initial_changeset ( & self ) -> Self :: ChangeSet {
262- super :: ChangeSet {
269+ ChangeSet {
263270 keychains_added : self
264271 . keychains ( )
265272 . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) )
@@ -485,8 +492,8 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
485492 & mut self ,
486493 keychain : K ,
487494 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 ( ) ;
490497 let desc_id = descriptor. descriptor_id ( ) ;
491498
492499 let old_desc_id = self
@@ -708,24 +715,40 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
708715 . descriptor_ids_to_descriptors
709716 . get ( descriptor_id)
710717 . 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 ( ) ;
712736
713- // we can only get the next index if the wildcard exists.
737+ // we can only get the next index if the wildcard exists
714738 let has_wildcard = descriptor. has_wildcard ( ) ;
739+ let last_index = self . last_revealed . get ( & desc_id) . cloned ( ) ;
715740
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
718743 None => ( 0 , true ) ,
719- // descriptors without wildcards can only have one index.
744+ // descriptors without wildcards can only have one index
720745 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" ) ,
725748 Some ( index) if index == BIP32_MAX_INDEX => ( index, false ) ,
726- // get the next derivation index.
749+ // get the next derivation index
727750 Some ( index) => ( index + 1 , true ) ,
728- } )
751+ }
729752 }
730753
731754 /// Get the last derivation index that is revealed for each keychain.
@@ -754,17 +777,16 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
754777 keychains : & BTreeMap < K , u32 > ,
755778 ) -> (
756779 BTreeMap < K , SpkIterator < Descriptor < DescriptorPublicKey > > > ,
757- super :: ChangeSet < K > ,
780+ ChangeSet < K > ,
758781 ) {
759- let mut changeset = super :: ChangeSet :: default ( ) ;
782+ let mut changeset = ChangeSet :: default ( ) ;
760783 let mut spks = BTreeMap :: new ( ) ;
761784
762785 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) ;
768790 }
769791 }
770792
@@ -777,18 +799,12 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
777799 /// Refer to the `reveal_to_target` documentation for more.
778800 ///
779801 /// 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 (
781803 & mut self ,
782- descriptor_id : DescriptorId ,
804+ descriptor : Descriptor < DescriptorPublicKey > ,
783805 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 ( ) ;
792808 let has_wildcard = descriptor. has_wildcard ( ) ;
793809
794810 let target_index = if has_wildcard { target_index } else { 0 } ;
@@ -801,10 +817,10 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
801817
802818 // If the target_index is already revealed, we are done
803819 if next_reveal_index > target_index {
804- return Some ( (
820+ return (
805821 SpkIterator :: new_with_range ( descriptor, next_reveal_index..next_reveal_index) ,
806- super :: ChangeSet :: default ( ) ,
807- ) ) ;
822+ ChangeSet :: default ( ) ,
823+ ) ;
808824 }
809825
810826 // 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> {
822838
823839 let _old_index = self . last_revealed . insert ( descriptor_id, target_index) ;
824840 debug_assert ! ( _old_index < Some ( target_index) ) ;
825- Some ( (
841+ (
826842 SpkIterator :: new_with_range ( descriptor, next_reveal_index..target_index + 1 ) ,
827- super :: ChangeSet {
843+ ChangeSet {
828844 keychains_added : BTreeMap :: new ( ) ,
829845 last_revealed : core:: iter:: once ( ( descriptor_id, target_index) ) . collect ( ) ,
830846 } ,
831- ) )
847+ )
832848 }
833849
834850 /// Reveals script pubkeys of the `keychain`'s descriptor **up to and including** the
@@ -839,76 +855,94 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
839855 /// reveal up to the last possible index.
840856 ///
841857 /// 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.
844860 ///
845861 /// Returns None if the provided `keychain` doesn't exist.
846862 pub fn reveal_to_target (
847863 & mut self ,
848864 keychain : & K ,
849865 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)
856881 }
857882
858883 /// Attempts to reveal the next script pubkey for `keychain`.
859884 ///
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 .
863888 ///
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:
866892 ///
867893 /// 1. The descriptor has no wildcard and already has one script revealed.
868894 /// 2. The descriptor has already revealed scripts up to the numeric bound.
869895 /// 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)
885922 }
886923
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) .
889926 ///
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.
891930 ///
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)).
895933 ///
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 ( ) )
905944 } 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)
912946 }
913947 }
914948
@@ -986,7 +1020,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
9861020 /// - Adds new descriptors introduced
9871021 /// - If a descriptor is introduced for a keychain that already had a descriptor, overwrites
9881022 /// the old descriptor
989- pub fn apply_changeset ( & mut self , changeset : super :: ChangeSet < K > ) {
1023+ pub fn apply_changeset ( & mut self , changeset : ChangeSet < K > ) {
9901024 let ChangeSet {
9911025 keychains_added,
9921026 last_revealed,
0 commit comments