Skip to content

Commit fd517ed

Browse files
committed
Move Electrum sync logic to a ElectrumChainSource type
We refactor our `ChainSource` logic and move out the Electrum code into a new object.
1 parent 8a01e17 commit fd517ed

File tree

2 files changed

+378
-347
lines changed

2 files changed

+378
-347
lines changed

src/chain/electrum.rs

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use electrum_client::Client as ElectrumClient;
3232
use electrum_client::ConfigBuilder as ElectrumConfigBuilder;
3333
use electrum_client::{Batch, ElectrumApi};
3434

35-
use bitcoin::{FeeRate, Network, Script, Transaction, Txid};
35+
use bitcoin::{FeeRate, Network, Script, ScriptBuf, Transaction, Txid};
3636

3737
use std::collections::HashMap;
3838
use std::sync::Arc;
@@ -42,7 +42,83 @@ const BDK_ELECTRUM_CLIENT_BATCH_SIZE: usize = 5;
4242
const ELECTRUM_CLIENT_NUM_RETRIES: u8 = 3;
4343
const ELECTRUM_CLIENT_TIMEOUT_SECS: u8 = 10;
4444

45-
pub(crate) struct ElectrumRuntimeClient {
45+
pub(super) enum ElectrumRuntimeStatus {
46+
Started(Arc<ElectrumRuntimeClient>),
47+
Stopped {
48+
pending_registered_txs: Vec<(Txid, ScriptBuf)>,
49+
pending_registered_outputs: Vec<WatchedOutput>,
50+
},
51+
}
52+
53+
impl ElectrumRuntimeStatus {
54+
pub(super) fn new() -> Self {
55+
let pending_registered_txs = Vec::new();
56+
let pending_registered_outputs = Vec::new();
57+
Self::Stopped { pending_registered_txs, pending_registered_outputs }
58+
}
59+
60+
pub(super) fn start(
61+
&mut self, server_url: String, runtime: Arc<tokio::runtime::Runtime>, config: Arc<Config>,
62+
logger: Arc<Logger>,
63+
) -> Result<(), Error> {
64+
match self {
65+
Self::Stopped { pending_registered_txs, pending_registered_outputs } => {
66+
let client = Arc::new(ElectrumRuntimeClient::new(
67+
server_url.clone(),
68+
runtime,
69+
config,
70+
logger,
71+
)?);
72+
73+
// Apply any pending `Filter` entries
74+
for (txid, script_pubkey) in pending_registered_txs.drain(..) {
75+
client.register_tx(&txid, &script_pubkey);
76+
}
77+
78+
for output in pending_registered_outputs.drain(..) {
79+
client.register_output(output)
80+
}
81+
82+
*self = Self::Started(client);
83+
},
84+
Self::Started(_) => {
85+
debug_assert!(false, "We shouldn't call start if we're already started")
86+
},
87+
}
88+
Ok(())
89+
}
90+
91+
pub(super) fn stop(&mut self) {
92+
*self = Self::new()
93+
}
94+
95+
pub(super) fn client(&self) -> Option<Arc<ElectrumRuntimeClient>> {
96+
match self {
97+
Self::Started(client) => Some(Arc::clone(&client)),
98+
Self::Stopped { .. } => None,
99+
}
100+
}
101+
102+
pub(super) fn register_tx(&mut self, txid: &Txid, script_pubkey: &Script) {
103+
match self {
104+
Self::Started(client) => client.register_tx(txid, script_pubkey),
105+
Self::Stopped { pending_registered_txs, .. } => {
106+
pending_registered_txs.push((*txid, script_pubkey.to_owned()))
107+
},
108+
}
109+
}
110+
111+
pub(super) fn register_output(&mut self, output: WatchedOutput) {
112+
match self {
113+
Self::Started(client) => client.register_output(output),
114+
Self::Stopped { pending_registered_outputs, .. } => {
115+
pending_registered_outputs.push(output)
116+
},
117+
}
118+
}
119+
}
120+
121+
pub(super) struct ElectrumRuntimeClient {
46122
electrum_client: Arc<ElectrumClient>,
47123
bdk_electrum_client: Arc<BdkElectrumClient<ElectrumClient>>,
48124
tx_sync: Arc<ElectrumSyncClient<Arc<Logger>>>,
@@ -52,7 +128,7 @@ pub(crate) struct ElectrumRuntimeClient {
52128
}
53129

54130
impl ElectrumRuntimeClient {
55-
pub(crate) fn new(
131+
pub(super) fn new(
56132
server_url: String, runtime: Arc<tokio::runtime::Runtime>, config: Arc<Config>,
57133
logger: Arc<Logger>,
58134
) -> Result<Self, Error> {
@@ -82,7 +158,7 @@ impl ElectrumRuntimeClient {
82158
Ok(Self { electrum_client, bdk_electrum_client, tx_sync, runtime, config, logger })
83159
}
84160

85-
pub(crate) async fn sync_confirmables(
161+
pub(super) async fn sync_confirmables(
86162
&self, confirmables: Vec<Arc<dyn Confirm + Sync + Send>>,
87163
) -> Result<(), Error> {
88164
let now = Instant::now();
@@ -116,7 +192,7 @@ impl ElectrumRuntimeClient {
116192
Ok(res)
117193
}
118194

119-
pub(crate) async fn get_full_scan_wallet_update(
195+
pub(super) async fn get_full_scan_wallet_update(
120196
&self, request: BdkFullScanRequest<BdkKeyChainKind>,
121197
cached_txs: impl IntoIterator<Item = impl Into<Arc<Transaction>>>,
122198
) -> Result<BdkFullScanResponse<BdkKeyChainKind>, Error> {
@@ -150,7 +226,7 @@ impl ElectrumRuntimeClient {
150226
})
151227
}
152228

153-
pub(crate) async fn get_incremental_sync_wallet_update(
229+
pub(super) async fn get_incremental_sync_wallet_update(
154230
&self, request: BdkSyncRequest<(BdkKeyChainKind, u32)>,
155231
cached_txs: impl IntoIterator<Item = impl Into<Arc<Transaction>>>,
156232
) -> Result<BdkSyncResponse, Error> {
@@ -179,7 +255,7 @@ impl ElectrumRuntimeClient {
179255
})
180256
}
181257

182-
pub(crate) async fn broadcast(&self, tx: Transaction) {
258+
pub(super) async fn broadcast(&self, tx: Transaction) {
183259
let electrum_client = Arc::clone(&self.electrum_client);
184260

185261
let txid = tx.compute_txid();
@@ -221,7 +297,7 @@ impl ElectrumRuntimeClient {
221297
}
222298
}
223299

224-
pub(crate) async fn get_fee_rate_cache_update(
300+
pub(super) async fn get_fee_rate_cache_update(
225301
&self,
226302
) -> Result<HashMap<ConfirmationTarget, FeeRate>, Error> {
227303
let electrum_client = Arc::clone(&self.electrum_client);

0 commit comments

Comments
 (0)