Skip to content

Commit 3de5c9d

Browse files
committed
Add timeout for broadcasting transactions
1 parent 49dbc03 commit 3de5c9d

File tree

2 files changed

+57
-29
lines changed

2 files changed

+57
-29
lines changed

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ pub(crate) const LDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 30;
5555
// The timeout after which we abort a fee rate cache update operation.
5656
pub(crate) const FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS: u64 = 5;
5757

58+
// The timeout after which we abort a transaction broadcast operation.
59+
pub(crate) const TX_BROADCAST_TIMEOUT_SECS: u64 = 5;
60+
5861
// The timeout after which we abort a RGS sync operation.
5962
pub(crate) const RGS_SYNC_TIMEOUT_SECS: u64 = 5;
6063

src/tx_broadcaster.rs

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::config::TX_BROADCAST_TIMEOUT_SECS;
12
use crate::logger::{log_bytes, log_error, log_trace, Logger};
23

34
use lightning::chain::chaininterface::BroadcasterInterface;
@@ -12,6 +13,7 @@ use tokio::sync::mpsc;
1213
use tokio::sync::Mutex;
1314

1415
use std::ops::Deref;
16+
use std::time::Duration;
1517

1618
const BCAST_PACKAGE_QUEUE_SIZE: usize = 50;
1719

@@ -38,45 +40,68 @@ where
3840
let mut receiver = self.queue_receiver.lock().await;
3941
while let Some(next_package) = receiver.recv().await {
4042
for tx in &next_package {
41-
match self.esplora_client.broadcast(tx).await {
42-
Ok(()) => {
43-
log_trace!(self.logger, "Successfully broadcast transaction {}", tx.txid());
44-
},
45-
Err(e) => match e {
46-
esplora_client::Error::Reqwest(err) => {
47-
if err.status() == StatusCode::from_u16(400).ok() {
48-
// Ignore 400, as this just means bitcoind already knows the
49-
// transaction.
50-
// FIXME: We can further differentiate here based on the error
51-
// message which will be available with rust-esplora-client 0.7 and
52-
// later.
53-
} else {
43+
let timeout_fut = tokio::time::timeout(
44+
Duration::from_secs(TX_BROADCAST_TIMEOUT_SECS),
45+
self.esplora_client.broadcast(tx),
46+
);
47+
match timeout_fut.await {
48+
Ok(res) => match res {
49+
Ok(()) => {
50+
log_trace!(
51+
self.logger,
52+
"Successfully broadcast transaction {}",
53+
tx.txid()
54+
);
55+
},
56+
Err(e) => match e {
57+
esplora_client::Error::Reqwest(err) => {
58+
if err.status() == StatusCode::from_u16(400).ok() {
59+
// Ignore 400, as this just means bitcoind already knows the
60+
// transaction.
61+
// FIXME: We can further differentiate here based on the error
62+
// message which will be available with rust-esplora-client 0.7 and
63+
// later.
64+
} else {
65+
log_error!(
66+
self.logger,
67+
"Failed to broadcast due to HTTP connection error: {}",
68+
err
69+
);
70+
}
71+
log_trace!(
72+
self.logger,
73+
"Failed broadcast transaction bytes: {}",
74+
log_bytes!(tx.encode())
75+
);
76+
},
77+
_ => {
5478
log_error!(
5579
self.logger,
56-
"Failed to broadcast due to HTTP connection error: {}",
57-
err
80+
"Failed to broadcast transaction {}: {}",
81+
tx.txid(),
82+
e
5883
);
5984
log_trace!(
6085
self.logger,
6186
"Failed broadcast transaction bytes: {}",
6287
log_bytes!(tx.encode())
6388
);
64-
}
65-
},
66-
_ => {
67-
log_error!(
68-
self.logger,
69-
"Failed to broadcast transaction {}: {}",
70-
tx.txid(),
71-
e
72-
);
73-
log_trace!(
74-
self.logger,
75-
"Failed broadcast transaction bytes: {}",
76-
log_bytes!(tx.encode())
77-
);
89+
},
7890
},
7991
},
92+
Err(e) => {
93+
log_error!(
94+
self.logger,
95+
"Failed to broadcast transaction due to timeout {}: {}",
96+
tx.txid(),
97+
e
98+
);
99+
log_trace!(
100+
self.logger,
101+
"Failed broadcast transaction bytes: {}",
102+
log_bytes!(tx.encode())
103+
);
104+
},
80105
}
81106
}
82107
}

0 commit comments

Comments
 (0)