66// accordance with one or both of these licenses.
77
88use std:: collections:: { HashMap , VecDeque } ;
9+ use std:: future:: Future ;
910use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
1011use std:: sync:: { Arc , Mutex , RwLock } ;
1112use std:: time:: { Duration , Instant , SystemTime , UNIX_EPOCH } ;
1213
1314use base64:: prelude:: BASE64_STANDARD ;
1415use base64:: Engine ;
15- use bitcoin:: { BlockHash , FeeRate , Network , Transaction , Txid } ;
16+ use bitcoin:: { BlockHash , FeeRate , Network , OutPoint , Transaction , Txid } ;
1617use lightning:: chain:: chaininterface:: ConfirmationTarget as LdkConfirmationTarget ;
1718use lightning:: chain:: { BestBlock , Listen } ;
1819use lightning:: util:: ser:: Writeable ;
@@ -23,7 +24,7 @@ use lightning_block_sync::poll::{ChainPoller, ChainTip, ValidatedBlockHeader};
2324use lightning_block_sync:: rest:: RestClient ;
2425use lightning_block_sync:: rpc:: { RpcClient , RpcError } ;
2526use lightning_block_sync:: {
26- AsyncBlockSourceResult , BlockData , BlockHeaderData , BlockSource , BlockSourceErrorKind , Cache ,
27+ BlockData , BlockHeaderData , BlockSource , BlockSourceError , BlockSourceErrorKind , Cache ,
2728 SpvClient ,
2829} ;
2930use serde:: Serialize ;
@@ -117,7 +118,7 @@ impl BitcoindChainSource {
117118 }
118119 }
119120
120- pub ( super ) fn as_utxo_source ( & self ) -> Arc < dyn UtxoSource > {
121+ pub ( super ) fn as_utxo_source ( & self ) -> UtxoSourceClient {
121122 self . api_client . utxo_source ( )
122123 }
123124
@@ -639,6 +640,78 @@ impl BitcoindChainSource {
639640 }
640641}
641642
643+ #[ derive( Clone ) ]
644+ pub ( crate ) enum UtxoSourceClient {
645+ Rpc ( Arc < RpcClient > ) ,
646+ Rest ( Arc < RestClient > ) ,
647+ }
648+
649+ impl std:: ops:: Deref for UtxoSourceClient {
650+ type Target = Self ;
651+ fn deref ( & self ) -> & Self {
652+ self
653+ }
654+ }
655+
656+ impl BlockSource for UtxoSourceClient {
657+ fn get_header < ' a > (
658+ & ' a self , header_hash : & ' a BlockHash , height_hint : Option < u32 > ,
659+ ) -> impl Future < Output = Result < BlockHeaderData , BlockSourceError > > + ' a {
660+ async move {
661+ match self {
662+ Self :: Rpc ( client) => client. get_header ( header_hash, height_hint) . await ,
663+ Self :: Rest ( client) => client. get_header ( header_hash, height_hint) . await ,
664+ }
665+ }
666+ }
667+
668+ fn get_block < ' a > (
669+ & ' a self , header_hash : & ' a BlockHash ,
670+ ) -> impl Future < Output = Result < BlockData , BlockSourceError > > + ' a {
671+ async move {
672+ match self {
673+ Self :: Rpc ( client) => client. get_block ( header_hash) . await ,
674+ Self :: Rest ( client) => client. get_block ( header_hash) . await ,
675+ }
676+ }
677+ }
678+
679+ fn get_best_block < ' a > (
680+ & ' a self ,
681+ ) -> impl Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + ' a {
682+ async move {
683+ match self {
684+ Self :: Rpc ( client) => client. get_best_block ( ) . await ,
685+ Self :: Rest ( client) => client. get_best_block ( ) . await ,
686+ }
687+ }
688+ }
689+ }
690+
691+ impl UtxoSource for UtxoSourceClient {
692+ fn get_block_hash_by_height < ' a > (
693+ & ' a self , block_height : u32 ,
694+ ) -> impl Future < Output = Result < BlockHash , BlockSourceError > > + ' a {
695+ async move {
696+ match self {
697+ Self :: Rpc ( client) => client. get_block_hash_by_height ( block_height) . await ,
698+ Self :: Rest ( client) => client. get_block_hash_by_height ( block_height) . await ,
699+ }
700+ }
701+ }
702+
703+ fn is_output_unspent < ' a > (
704+ & ' a self , outpoint : OutPoint ,
705+ ) -> impl Future < Output = Result < bool , BlockSourceError > > + ' a {
706+ async move {
707+ match self {
708+ Self :: Rpc ( client) => client. is_output_unspent ( outpoint) . await ,
709+ Self :: Rest ( client) => client. is_output_unspent ( outpoint) . await ,
710+ }
711+ }
712+ }
713+ }
714+
642715pub enum BitcoindClient {
643716 Rpc {
644717 rpc_client : Arc < RpcClient > ,
@@ -700,12 +773,10 @@ impl BitcoindClient {
700773 }
701774 }
702775
703- pub ( crate ) fn utxo_source ( & self ) -> Arc < dyn UtxoSource > {
776+ fn utxo_source ( & self ) -> UtxoSourceClient {
704777 match self {
705- BitcoindClient :: Rpc { rpc_client, .. } => Arc :: clone ( rpc_client) as Arc < dyn UtxoSource > ,
706- BitcoindClient :: Rest { rest_client, .. } => {
707- Arc :: clone ( rest_client) as Arc < dyn UtxoSource >
708- } ,
778+ Self :: Rpc { rpc_client, .. } => UtxoSourceClient :: Rpc ( Arc :: clone ( & rpc_client) ) ,
779+ Self :: Rest { rest_client, .. } => UtxoSourceClient :: Rest ( Arc :: clone ( & rest_client) ) ,
709780 }
710781 }
711782
@@ -1189,38 +1260,40 @@ impl BitcoindClient {
11891260impl BlockSource for BitcoindClient {
11901261 fn get_header < ' a > (
11911262 & ' a self , header_hash : & ' a bitcoin:: BlockHash , height_hint : Option < u32 > ,
1192- ) -> AsyncBlockSourceResult < ' a , BlockHeaderData > {
1193- match self {
1194- BitcoindClient :: Rpc { rpc_client, .. } => {
1195- Box :: pin ( async move { rpc_client. get_header ( header_hash, height_hint) . await } )
1196- } ,
1197- BitcoindClient :: Rest { rest_client, .. } => {
1198- Box :: pin ( async move { rest_client. get_header ( header_hash, height_hint) . await } )
1199- } ,
1263+ ) -> impl Future < Output = Result < BlockHeaderData , BlockSourceError > > + ' a {
1264+ async move {
1265+ match self {
1266+ BitcoindClient :: Rpc { rpc_client, .. } => {
1267+ rpc_client. get_header ( header_hash, height_hint) . await
1268+ } ,
1269+ BitcoindClient :: Rest { rest_client, .. } => {
1270+ rest_client. get_header ( header_hash, height_hint) . await
1271+ } ,
1272+ }
12001273 }
12011274 }
12021275
12031276 fn get_block < ' a > (
12041277 & ' a self , header_hash : & ' a bitcoin:: BlockHash ,
1205- ) -> AsyncBlockSourceResult < ' a , BlockData > {
1206- match self {
1207- BitcoindClient :: Rpc { rpc_client , .. } => {
1208- Box :: pin ( async move { rpc_client. get_block ( header_hash) . await } )
1209- } ,
1210- BitcoindClient :: Rest { rest_client, .. } => {
1211- Box :: pin ( async move { rest_client . get_block ( header_hash ) . await } )
1212- } ,
1278+ ) -> impl Future < Output = Result < BlockData , BlockSourceError > > + ' a {
1279+ async move {
1280+ match self {
1281+ BitcoindClient :: Rpc { rpc_client, .. } => rpc_client . get_block ( header_hash) . await ,
1282+ BitcoindClient :: Rest { rest_client , .. } => {
1283+ rest_client. get_block ( header_hash ) . await
1284+ } ,
1285+ }
12131286 }
12141287 }
12151288
1216- fn get_best_block ( & self ) -> AsyncBlockSourceResult < ' _ , ( bitcoin :: BlockHash , Option < u32 > ) > {
1217- match self {
1218- BitcoindClient :: Rpc { rpc_client , .. } => {
1219- Box :: pin ( async move { rpc_client . get_best_block ( ) . await } )
1220- } ,
1221- BitcoindClient :: Rest { rest_client , .. } => {
1222- Box :: pin ( async move { rest_client. get_best_block ( ) . await } )
1223- } ,
1289+ fn get_best_block < ' a > (
1290+ & ' a self ,
1291+ ) -> impl Future < Output = Result < ( bitcoin :: BlockHash , Option < u32 > ) , BlockSourceError > > + ' a {
1292+ async move {
1293+ match self {
1294+ BitcoindClient :: Rpc { rpc_client , .. } => rpc_client . get_best_block ( ) . await ,
1295+ BitcoindClient :: Rest { rest_client, .. } => rest_client . get_best_block ( ) . await ,
1296+ }
12241297 }
12251298 }
12261299}
0 commit comments