Skip to content

Commit 98150cd

Browse files
committed
Implement process_broadcast_queue for ChainSource::Electrum
1 parent 6ead9be commit 98150cd

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

src/chain/electrum.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,24 @@
55
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66
// accordance with one or both of these licenses.
77

8+
use crate::config::TX_BROADCAST_TIMEOUT_SECS;
89
use crate::error::Error;
9-
use crate::logger::{log_error, LdkLogger, Logger};
10+
use crate::logger::{log_bytes, log_error, log_trace, LdkLogger, Logger};
1011

1112
use lightning::chain::{Filter, WatchedOutput};
13+
use lightning::util::ser::Writeable;
1214
use lightning_transaction_sync::ElectrumSyncClient;
1315

1416
use bdk_electrum::BdkElectrumClient;
1517

1618
use electrum_client::Client as ElectrumClient;
1719
use electrum_client::ConfigBuilder as ElectrumConfigBuilder;
20+
use electrum_client::ElectrumApi;
1821

19-
use bitcoin::{Script, Txid};
22+
use bitcoin::{Script, Transaction, Txid};
2023

2124
use std::sync::Arc;
25+
use std::time::Duration;
2226

2327
const ELECTRUM_CLIENT_NUM_RETRIES: u8 = 3;
2428
const ELECTRUM_CLIENT_TIMEOUT_SECS: u8 = 20;
@@ -60,6 +64,48 @@ impl ElectrumRuntimeClient {
6064
);
6165
Ok(Self { electrum_client, bdk_electrum_client, tx_sync, runtime, logger })
6266
}
67+
68+
pub(crate) async fn broadcast(&self, tx: Transaction) {
69+
let electrum_client = Arc::clone(&self.electrum_client);
70+
71+
let txid = tx.compute_txid();
72+
let tx_bytes = tx.encode();
73+
74+
let spawn_fut =
75+
self.runtime.spawn_blocking(move || electrum_client.transaction_broadcast(&tx));
76+
77+
let timeout_fut =
78+
tokio::time::timeout(Duration::from_secs(TX_BROADCAST_TIMEOUT_SECS), spawn_fut);
79+
80+
match timeout_fut.await {
81+
Ok(res) => match res {
82+
Ok(_) => {
83+
log_trace!(self.logger, "Successfully broadcast transaction {}", txid);
84+
},
85+
Err(e) => {
86+
log_error!(self.logger, "Failed to broadcast transaction {}: {}", txid, e);
87+
log_trace!(
88+
self.logger,
89+
"Failed broadcast transaction bytes: {}",
90+
log_bytes!(tx_bytes)
91+
);
92+
},
93+
},
94+
Err(e) => {
95+
log_error!(
96+
self.logger,
97+
"Failed to broadcast transaction due to timeout {}: {}",
98+
txid,
99+
e
100+
);
101+
log_trace!(
102+
self.logger,
103+
"Failed broadcast transaction bytes: {}",
104+
log_bytes!(tx_bytes)
105+
);
106+
},
107+
}
108+
}
63109
}
64110

65111
impl Filter for ElectrumRuntimeClient {

src/chain/mod.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ impl ElectrumRuntimeStatus {
154154
*self = Self::new()
155155
}
156156

157-
pub(crate) fn client(&self) -> Option<&ElectrumRuntimeClient> {
157+
pub(crate) fn client(&self) -> Option<Arc<ElectrumRuntimeClient>> {
158158
match self {
159-
Self::Started(client) => Some(&*client),
159+
Self::Started(client) => Some(Arc::clone(&client)),
160160
Self::Stopped { .. } => None,
161161
}
162162
}
@@ -1266,7 +1266,26 @@ impl ChainSource {
12661266
}
12671267
}
12681268
},
1269-
Self::Electrum { .. } => todo!(),
1269+
Self::Electrum { electrum_runtime_status, tx_broadcaster, .. } => {
1270+
let electrum_client: Arc<ElectrumRuntimeClient> = if let Some(client) =
1271+
electrum_runtime_status.read().unwrap().client().as_ref()
1272+
{
1273+
Arc::clone(client)
1274+
} else {
1275+
debug_assert!(
1276+
false,
1277+
"We should have started the chain source before broadcasting"
1278+
);
1279+
return;
1280+
};
1281+
1282+
let mut receiver = tx_broadcaster.get_broadcast_queue().await;
1283+
while let Some(next_package) = receiver.recv().await {
1284+
for tx in next_package {
1285+
electrum_client.broadcast(tx).await;
1286+
}
1287+
}
1288+
},
12701289
Self::BitcoindRpc { bitcoind_rpc_client, tx_broadcaster, logger, .. } => {
12711290
// While it's a bit unclear when we'd be able to lean on Bitcoin Core >v28
12721291
// features, we should eventually switch to use `submitpackage` via the

0 commit comments

Comments
 (0)