Skip to content

Commit a1acfd9

Browse files
committed
Implement (cached) Filter for ElectrumRuntimeClient
Currently, we won't have a `Runtime` available when initializing `ChainSource::Electrum`. We therefore isolate any runtime-specific behavior into an `ElectrumRuntimeClient`. Here, we implement `Filter` for `ElectrumRuntimeClient`, but we need to cache the registrations as they might happen prior to `ElectrumRuntimeClient` becoming available.
1 parent 0799c2a commit a1acfd9

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

src/chain/electrum.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
use crate::error::Error;
99
use crate::logger::{log_error, LdkLogger, Logger};
1010

11+
use lightning::chain::{Filter, WatchedOutput};
1112
use lightning_transaction_sync::ElectrumSyncClient;
1213

1314
use bdk_electrum::BdkElectrumClient;
1415

1516
use electrum_client::Client as ElectrumClient;
1617

18+
use bitcoin::{Script, Txid};
19+
1720
use std::sync::Arc;
1821

1922
pub(crate) struct ElectrumRuntimeClient {
@@ -46,3 +49,12 @@ impl ElectrumRuntimeClient {
4649
Ok(Self { electrum_client, bdk_electrum_client, tx_sync, runtime, logger })
4750
}
4851
}
52+
53+
impl Filter for ElectrumRuntimeClient {
54+
fn register_tx(&self, txid: &Txid, script_pubkey: &Script) {
55+
self.tx_sync.register_tx(txid, script_pubkey)
56+
}
57+
fn register_output(&self, output: WatchedOutput) {
58+
self.tx_sync.register_output(output)
59+
}
60+
}

src/chain/mod.rs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::types::{Broadcaster, ChainMonitor, ChannelManager, DynStore, Sweeper,
2828
use crate::{Error, NodeMetrics};
2929

3030
use lightning::chain::chaininterface::ConfirmationTarget as LdkConfirmationTarget;
31-
use lightning::chain::{Confirm, Filter, Listen};
31+
use lightning::chain::{Confirm, Filter, Listen, WatchedOutput};
3232
use lightning::util::ser::Writeable;
3333

3434
use lightning_transaction_sync::EsploraSyncClient;
@@ -42,7 +42,7 @@ use bdk_esplora::EsploraAsyncExt;
4242

4343
use esplora_client::AsyncClient as EsploraAsyncClient;
4444

45-
use bitcoin::{FeeRate, Network};
45+
use bitcoin::{FeeRate, Network, Script, ScriptBuf, Txid};
4646

4747
use std::collections::HashMap;
4848
use std::sync::{Arc, Mutex, RwLock};
@@ -128,6 +128,8 @@ pub(crate) enum ChainSource {
128128
server_url: String,
129129
sync_config: ElectrumSyncConfig,
130130
electrum_runtime_client: RwLock<Option<ElectrumRuntimeClient>>,
131+
registered_txs_cache: Mutex<Vec<(Txid, ScriptBuf)>>,
132+
registered_outputs_cache: Mutex<Vec<WatchedOutput>>,
131133
onchain_wallet: Arc<Wallet>,
132134
onchain_wallet_sync_status: Mutex<WalletSyncStatus>,
133135
lightning_wallet_sync_status: Mutex<WalletSyncStatus>,
@@ -190,12 +192,16 @@ impl ChainSource {
190192
node_metrics: Arc<RwLock<NodeMetrics>>,
191193
) -> Self {
192194
let electrum_runtime_client = RwLock::new(None);
195+
let registered_txs_cache = Mutex::new(Vec::new());
196+
let registered_outputs_cache = Mutex::new(Vec::new());
193197
let onchain_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);
194198
let lightning_wallet_sync_status = Mutex::new(WalletSyncStatus::Completed);
195199
Self::Electrum {
196200
server_url,
197201
sync_config,
198202
electrum_runtime_client,
203+
registered_txs_cache,
204+
registered_outputs_cache,
199205
onchain_wallet,
200206
onchain_wallet_sync_status,
201207
lightning_wallet_sync_status,
@@ -236,13 +242,36 @@ impl ChainSource {
236242

237243
pub(crate) fn start(&self, runtime: Arc<tokio::runtime::Runtime>) -> Result<(), Error> {
238244
match self {
239-
Self::Electrum { server_url, electrum_runtime_client, logger, .. } => {
245+
Self::Electrum {
246+
server_url,
247+
electrum_runtime_client,
248+
registered_txs_cache,
249+
registered_outputs_cache,
250+
logger,
251+
..
252+
} => {
240253
let mut locked_client = electrum_runtime_client.write().unwrap();
241-
*locked_client = Some(ElectrumRuntimeClient::new(
242-
server_url.clone(),
243-
runtime,
244-
Arc::clone(&logger),
245-
)?);
254+
let client =
255+
ElectrumRuntimeClient::new(server_url.clone(), runtime, Arc::clone(&logger))?;
256+
257+
// Apply any previously-cached `Filter` entries
258+
{
259+
let registered_txs_cache =
260+
core::mem::take(&mut *registered_txs_cache.lock().unwrap());
261+
for (txid, script_pubkey) in registered_txs_cache {
262+
client.register_tx(&txid, &script_pubkey);
263+
}
264+
}
265+
266+
{
267+
let registered_outputs_cache =
268+
core::mem::take(&mut *registered_outputs_cache.lock().unwrap());
269+
for output in registered_outputs_cache {
270+
client.register_output(output)
271+
}
272+
}
273+
274+
*locked_client = Some(client);
246275
},
247276
_ => {
248277
// Nothing to do for other chain sources.
@@ -1213,17 +1242,29 @@ impl ChainSource {
12131242
}
12141243

12151244
impl Filter for ChainSource {
1216-
fn register_tx(&self, txid: &bitcoin::Txid, script_pubkey: &bitcoin::Script) {
1245+
fn register_tx(&self, txid: &Txid, script_pubkey: &Script) {
12171246
match self {
12181247
Self::Esplora { tx_sync, .. } => tx_sync.register_tx(txid, script_pubkey),
1219-
Self::Electrum { .. } => todo!(),
1248+
Self::Electrum { electrum_runtime_client, registered_txs_cache, .. } => {
1249+
match electrum_runtime_client.read().unwrap().as_ref() {
1250+
Some(client) => client.register_tx(txid, script_pubkey),
1251+
None => {
1252+
registered_txs_cache.lock().unwrap().push((*txid, script_pubkey.to_owned()))
1253+
},
1254+
}
1255+
},
12201256
Self::BitcoindRpc { .. } => (),
12211257
}
12221258
}
12231259
fn register_output(&self, output: lightning::chain::WatchedOutput) {
12241260
match self {
12251261
Self::Esplora { tx_sync, .. } => tx_sync.register_output(output),
1226-
Self::Electrum { .. } => todo!(),
1262+
Self::Electrum { electrum_runtime_client, registered_outputs_cache, .. } => {
1263+
match electrum_runtime_client.read().unwrap().as_ref() {
1264+
Some(client) => client.register_output(output),
1265+
None => registered_outputs_cache.lock().unwrap().push(output),
1266+
}
1267+
},
12271268
Self::BitcoindRpc { .. } => (),
12281269
}
12291270
}

0 commit comments

Comments
 (0)