22//! current UTXO set. This module defines an implementation of the LDK API required to do so
33//! against a [`BlockSource`] which implements a few additional methods for accessing the UTXO set.
44
5- use crate :: { AsyncBlockSourceResult , BlockData , BlockSource , BlockSourceError } ;
5+ use crate :: { BlockData , BlockSource , BlockSourceError , BlockSourceResult } ;
66
77use bitcoin:: block:: Block ;
88use bitcoin:: constants:: ChainHash ;
@@ -18,7 +18,7 @@ use lightning::util::native_async::FutureSpawner;
1818use std:: collections:: VecDeque ;
1919use std:: future:: Future ;
2020use std:: ops:: Deref ;
21- use std:: pin:: Pin ;
21+ use std:: pin:: { pin , Pin } ;
2222use std:: sync:: { Arc , Mutex } ;
2323use std:: task:: Poll ;
2424
@@ -35,11 +35,13 @@ pub trait UtxoSource: BlockSource + 'static {
3535 /// for gossip validation.
3636 fn get_block_hash_by_height < ' a > (
3737 & ' a self , block_height : u32 ,
38- ) -> AsyncBlockSourceResult < ' a , BlockHash > ;
38+ ) -> impl Future < Output = BlockSourceResult < BlockHash > > + Send + ' a ;
3939
4040 /// Returns true if the given output has *not* been spent, i.e. is a member of the current UTXO
4141 /// set.
42- fn is_output_unspent < ' a > ( & ' a self , outpoint : OutPoint ) -> AsyncBlockSourceResult < ' a , bool > ;
42+ fn is_output_unspent < ' a > (
43+ & ' a self , outpoint : OutPoint ,
44+ ) -> impl Future < Output = BlockSourceResult < bool > > + Send + ' a ;
4345}
4446
4547#[ cfg( feature = "tokio" ) ]
@@ -55,34 +57,37 @@ impl FutureSpawner for TokioSpawner {
5557/// A trivial future which joins two other futures and polls them at the same time, returning only
5658/// once both complete.
5759pub ( crate ) struct Joiner <
58- A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
59- B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
60+ ' a ,
61+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > ,
62+ B : Future < Output = Result < BlockHash , BlockSourceError > > ,
6063> {
61- pub a : A ,
62- pub b : B ,
64+ pub a : Pin < & ' a mut A > ,
65+ pub b : Pin < & ' a mut B > ,
6366 a_res : Option < ( BlockHash , Option < u32 > ) > ,
6467 b_res : Option < BlockHash > ,
6568}
6669
6770impl <
68- A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
69- B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
70- > Joiner < A , B >
71+ ' a ,
72+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > ,
73+ B : Future < Output = Result < BlockHash , BlockSourceError > > ,
74+ > Joiner < ' a , A , B >
7175{
72- fn new ( a : A , b : B ) -> Self {
76+ fn new ( a : Pin < & ' a mut A > , b : Pin < & ' a mut B > ) -> Self {
7377 Self { a, b, a_res : None , b_res : None }
7478 }
7579}
7680
7781impl <
78- A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
79- B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
80- > Future for Joiner < A , B >
82+ ' a ,
83+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > ,
84+ B : Future < Output = Result < BlockHash , BlockSourceError > > ,
85+ > Future for Joiner < ' a , A , B >
8186{
8287 type Output = Result < ( ( BlockHash , Option < u32 > ) , BlockHash ) , BlockSourceError > ;
8388 fn poll ( mut self : Pin < & mut Self > , ctx : & mut core:: task:: Context < ' _ > ) -> Poll < Self :: Output > {
8489 if self . a_res . is_none ( ) {
85- match Pin :: new ( & mut self . a ) . poll ( ctx) {
90+ match self . a . as_mut ( ) . poll ( ctx) {
8691 Poll :: Ready ( res) => {
8792 if let Ok ( ok) = res {
8893 self . a_res = Some ( ok) ;
9499 }
95100 }
96101 if self . b_res . is_none ( ) {
97- match Pin :: new ( & mut self . b ) . poll ( ctx) {
102+ match self . b . as_mut ( ) . poll ( ctx) {
98103 Poll :: Ready ( res) => {
99104 if let Ok ( ok) = res {
100105 self . b_res = Some ( ok) ;
@@ -200,10 +205,12 @@ where
200205 }
201206 }
202207
203- let ( ( _, tip_height_opt) , block_hash) =
204- Joiner :: new ( source. get_best_block ( ) , source. get_block_hash_by_height ( block_height) )
205- . await
206- . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
208+ let ( ( _, tip_height_opt) , block_hash) = Joiner :: new (
209+ pin ! ( source. get_best_block( ) ) ,
210+ pin ! ( source. get_block_hash_by_height( block_height) ) ,
211+ )
212+ . await
213+ . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
207214 if let Some ( tip_height) = tip_height_opt {
208215 // If the block doesn't yet have five confirmations, error out.
209216 //
0 commit comments