@@ -26,7 +26,7 @@ pub struct BdkElectrumClient<E> {
26
26
/// The header cache
27
27
block_header_cache : Mutex < HashMap < u32 , Header > > ,
28
28
/// The Merkle proof cache
29
- merkle_cache : Mutex < HashMap < ( Txid , u32 ) , GetMerkleRes > > ,
29
+ merkle_cache : Mutex < HashMap < ( Txid , BlockHash ) , GetMerkleRes > > ,
30
30
}
31
31
32
32
impl < E : ElectrumApi > BdkElectrumClient < E > {
@@ -456,33 +456,39 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
456
456
& self ,
457
457
txs_with_heights : & [ ( Txid , usize ) ] ,
458
458
) -> Result < Vec < ( Txid , GetMerkleRes ) > , Error > {
459
- let mut results = Vec :: with_capacity ( txs_with_heights. len ( ) ) ;
459
+ let mut proofs = Vec :: with_capacity ( txs_with_heights. len ( ) ) ;
460
460
let mut to_fetch = Vec :: new ( ) ;
461
461
462
- // Check cache first
462
+ // First check the cache
463
463
{
464
464
let merkle_cache = self . merkle_cache . lock ( ) . unwrap ( ) ;
465
465
for & ( txid, height) in txs_with_heights {
466
- if let Some ( proof) = merkle_cache. get ( & ( txid, height as u32 ) ) {
467
- results. push ( ( txid, proof. clone ( ) ) ) ;
466
+ let header = self . fetch_header ( height as u32 ) ?;
467
+ if let Some ( proof) = merkle_cache. get ( & ( txid, header. block_hash ( ) ) ) {
468
+ proofs. push ( ( txid, proof. clone ( ) ) ) ;
468
469
} else {
469
470
to_fetch. push ( ( txid, height) ) ;
470
471
}
471
472
}
472
473
}
473
474
474
- // Fetch missing proofs in batches
475
+ // Then fetch what's missing
475
476
for chunk in to_fetch. chunks ( MAX_MERKLE_BATCH_SIZE ) {
476
- for & ( txid, height) in chunk {
477
- if let Ok ( merkle_res) = self . inner . transaction_get_merkle ( & txid, height) {
478
- let mut cache = self . merkle_cache . lock ( ) . unwrap ( ) ;
479
- cache. insert ( ( txid, height as u32 ) , merkle_res. clone ( ) ) ;
480
- results. push ( ( txid, merkle_res) ) ;
481
- }
477
+ let mut chunk_proofs = self
478
+ . inner
479
+ . batch_transaction_get_merkle ( chunk. iter ( ) . map ( |& ( txid, height) | ( txid, height) ) ) ?;
480
+
481
+ // Update cache
482
+ let mut cache = self . merkle_cache . lock ( ) . unwrap ( ) ;
483
+ for ( ( txid, height) , proof) in chunk. iter ( ) . zip ( chunk_proofs. iter ( ) ) {
484
+ let header = self . fetch_header ( * height as u32 ) ?;
485
+ cache. insert ( ( txid. clone ( ) , header. block_hash ( ) ) , proof. clone ( ) ) ;
482
486
}
487
+
488
+ proofs. extend ( chunk_proofs. into_iter ( ) . zip ( chunk) . map ( |( p, ( t, _) ) | ( t, p) ) ) ;
483
489
}
484
490
485
- Ok ( results )
491
+ Ok ( proofs )
486
492
}
487
493
488
494
/// Batch validate Merkle proofs
@@ -542,18 +548,6 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
542
548
Ok ( ( ) )
543
549
}
544
550
545
- // Replace the old validate_merkle_for_anchor with optimized batch version
546
- fn validate_merkle_for_anchor (
547
- & self ,
548
- tx_update : & mut TxUpdate < ConfirmationBlockTime > ,
549
- txid : Txid ,
550
- confirmation_height : usize ,
551
- ) -> Result < ( ) , Error > {
552
- // Use the batch processing functions even for single tx
553
- let proofs = self . batch_fetch_merkle_proofs ( & [ ( txid, confirmation_height) ] ) ?;
554
- self . batch_validate_merkle_proofs ( tx_update, proofs)
555
- }
556
-
557
551
// Helper function which fetches the `TxOut`s of our relevant transactions' previous transactions,
558
552
// which we do not have by default. This data is needed to calculate the transaction fee.
559
553
fn fetch_prev_txout (
0 commit comments