@@ -365,15 +365,17 @@ impl EsploraChainSource {
365365 }
366366
367367 pub ( crate ) async fn process_broadcast_package ( & self , package : Vec < Transaction > ) {
368- for tx in & package {
368+ if package. len ( ) == 1 {
369+ let tx = & package[ 0 ] ;
369370 let txid = tx. compute_txid ( ) ;
370371 let timeout_fut = tokio:: time:: timeout (
371372 Duration :: from_secs ( TX_BROADCAST_TIMEOUT_SECS ) ,
372373 self . esplora_client . broadcast ( tx) ,
373374 ) ;
374375 match timeout_fut. await {
375376 Ok ( res) => match res {
376- Ok ( ( ) ) => {
377+ Ok ( id) => {
378+ debug_assert_eq ! ( id, txid) ;
377379 log_trace ! ( self . logger, "Successfully broadcast transaction {}" , txid) ;
378380 } ,
379381 Err ( e) => match e {
@@ -432,6 +434,82 @@ impl EsploraChainSource {
432434 ) ;
433435 } ,
434436 }
437+ } else if package. len ( ) > 1 {
438+ let txids: Vec < _ > = package. iter ( ) . map ( |tx| tx. compute_txid ( ) ) . collect ( ) ;
439+ let timeout_fut = tokio:: time:: timeout (
440+ Duration :: from_secs ( TX_BROADCAST_TIMEOUT_SECS ) ,
441+ self . esplora_client . submit_package ( & package, None , None ) ,
442+ ) ;
443+ match timeout_fut. await {
444+ Ok ( res) => match res {
445+ Ok ( result) => {
446+ let mut ids: Vec < _ > =
447+ result. tx_results . values ( ) . map ( |value| value. txid ) . collect ( ) ;
448+ // TODO: seems we don't get the txids back in the same order...
449+ ids. sort_unstable ( ) ;
450+ let mut sorted_txids = txids. clone ( ) ;
451+ sorted_txids. sort_unstable ( ) ;
452+ debug_assert_eq ! ( ids, sorted_txids) ;
453+ log_trace ! (
454+ self . logger,
455+ "Package broadcast message {}, txids: {:?}" ,
456+ result. package_msg,
457+ txids,
458+ ) ;
459+ } ,
460+ Err ( e) => match e {
461+ esplora_client:: Error :: HttpResponse { status, message } => {
462+ if status == 400 {
463+ // Log 400 at lesser level, as this often just means bitcoind already knows the
464+ // transaction.
465+ // FIXME: We can further differentiate here based on the error
466+ // message which will be available with rust-esplora-client 0.7 and
467+ // later.
468+ log_trace ! (
469+ self . logger,
470+ "Failed to broadcast due to HTTP connection error: {}" ,
471+ message
472+ ) ;
473+ } else {
474+ log_error ! (
475+ self . logger,
476+ "Failed to broadcast due to HTTP connection error: {} - {}" ,
477+ status,
478+ message
479+ ) ;
480+ }
481+ log_trace ! ( self . logger, "Failed broadcast package bytes:" ) ;
482+ for tx in package {
483+ log_trace ! ( self . logger, "{}" , log_bytes!( tx. encode( ) ) ) ;
484+ }
485+ } ,
486+ _ => {
487+ log_error ! (
488+ self . logger,
489+ "Failed to broadcast package {:?}: {}" ,
490+ txids,
491+ e
492+ ) ;
493+ log_trace ! ( self . logger, "Failed broadcast package bytes:" ) ;
494+ for tx in package {
495+ log_trace ! ( self . logger, "{}" , log_bytes!( tx. encode( ) ) ) ;
496+ }
497+ } ,
498+ } ,
499+ } ,
500+ Err ( e) => {
501+ log_error ! (
502+ self . logger,
503+ "Failed to broadcast package due to timeout {:?}: {}" ,
504+ txids,
505+ e
506+ ) ;
507+ log_trace ! ( self . logger, "Failed broadcast transaction bytes:" ) ;
508+ for tx in package {
509+ log_trace ! ( self . logger, "{}" , log_bytes!( tx. encode( ) ) ) ;
510+ }
511+ } ,
512+ }
435513 }
436514 }
437515}
0 commit comments