@@ -12,9 +12,6 @@ use std::sync::{Arc, Mutex};
1212/// We include a chain suffix of a certain length for the purpose of robustness.
1313const CHAIN_SUFFIX_LENGTH : u32 = 8 ;
1414
15- /// Maximum batch size for proof validation requests
16- const MAX_BATCH_SIZE : usize = 100 ;
17-
1815/// Wrapper around an [`electrum_client::ElectrumApi`] which includes an internal in-memory
1916/// transaction cache to avoid re-fetching already downloaded transactions.
2017#[ derive( Debug ) ]
@@ -499,35 +496,42 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
499496 }
500497 }
501498
502- // Fetch missing proofs in batches
503- for chunk in to_fetch. chunks ( MAX_BATCH_SIZE ) {
504- for & ( txid, height, hash) in chunk {
505- // Fetch the raw proof.
506- let proof = self . inner . transaction_get_merkle ( & txid, height) ?;
507-
508- // Validate against header, retrying once on stale header.
509- let mut header = {
510- let cache = self . block_header_cache . lock ( ) . unwrap ( ) ;
511- cache[ & ( height as u32 ) ]
512- } ;
513- let mut valid = electrum_client:: utils:: validate_merkle_proof (
499+ // Batch all get_merkle calls.
500+ let mut batch = electrum_client:: Batch :: default ( ) ;
501+ for & ( txid, height, _) in & to_fetch {
502+ batch. raw (
503+ "blockchain.transaction.get_merkle" . into ( ) ,
504+ vec ! [
505+ electrum_client:: Param :: String ( format!( "{:x}" , txid) ) ,
506+ electrum_client:: Param :: Usize ( height) ,
507+ ] ,
508+ ) ;
509+ }
510+ let resps = self . inner . batch_call ( & batch) ?;
511+
512+ // Validate each proof, retrying once for each stale header.
513+ for ( ( txid, height, hash) , resp) in to_fetch. into_iter ( ) . zip ( resps. into_iter ( ) ) {
514+ let proof: electrum_client:: GetMerkleRes = serde_json:: from_value ( resp) ?;
515+
516+ let mut header = {
517+ let cache = self . block_header_cache . lock ( ) . unwrap ( ) ;
518+ cache[ & ( height as u32 ) ]
519+ } ;
520+ let mut valid =
521+ electrum_client:: utils:: validate_merkle_proof ( & txid, & header. merkle_root , & proof) ;
522+ if !valid {
523+ let new_header = self . inner . block_header ( height) ?;
524+ self . block_header_cache
525+ . lock ( )
526+ . unwrap ( )
527+ . insert ( height as u32 , new_header) ;
528+ header = new_header;
529+ valid = electrum_client:: utils:: validate_merkle_proof (
514530 & txid,
515531 & header. merkle_root ,
516532 & proof,
517533 ) ;
518- if !valid {
519- let new_header = self . inner . block_header ( height) ?;
520- self . block_header_cache
521- . lock ( )
522- . unwrap ( )
523- . insert ( height as u32 , new_header) ;
524- header = new_header;
525- valid = electrum_client:: utils:: validate_merkle_proof (
526- & txid,
527- & header. merkle_root ,
528- & proof,
529- ) ;
530- }
534+ }
531535
532536 // Build and cache the anchor if merkle proof is valid.
533537 if valid {
0 commit comments