Skip to content

Commit 9b22afe

Browse files
author
+Sharon
committed
Add populate_anchor_cache method to bdk
1 parent d9c2b95 commit 9b22afe

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

crates/electrum/src/bdk_electrum_client.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use bdk_core::{
88
};
99
use electrum_client::{ElectrumApi, Error, HeaderNotification};
1010
use std::sync::{Arc, Mutex};
11+
use std::convert::TryInto;
12+
1113

1214
/// We include a chain suffix of a certain length for the purpose of robustness.
1315
const CHAIN_SUFFIX_LENGTH: u32 = 8;
@@ -37,6 +39,18 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
3739
}
3840
}
3941

42+
/// Insert anchors into the anchor cache so that they don’t have to be fetched again from Electrum.
43+
/// Typically used to pre-populate the cache from an existing `TxGraph`.
44+
pub fn populate_anchor_cache(
45+
&self,
46+
anchors: impl IntoIterator<Item = ((Txid, BlockHash), ConfirmationBlockTime)>,
47+
) {
48+
let mut cache = self.anchor_cache.lock().unwrap();
49+
for ((txid, block_hash), anchor) in anchors {
50+
cache.insert((txid, block_hash), anchor);
51+
}
52+
}
53+
4054
/// Inserts transactions into the transaction cache so that the client will not fetch these
4155
/// transactions.
4256
pub fn populate_tx_cache(&self, txs: impl IntoIterator<Item = impl Into<Arc<Transaction>>>) {

examples/example_electrum/src/main.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::io::{self, Write};
22

33
use bdk_chain::{
4-
bitcoin::Network,
4+
bitcoin::{Network,Txid, BlockHash},
55
collections::BTreeSet,
66
indexed_tx_graph,
7+
TxGraph,
78
spk_client::{FullScanRequest, SyncRequest},
89
CanonicalizationParams, ConfirmationBlockTime, Merge,
910
};
@@ -94,6 +95,28 @@ pub struct ScanOptions {
9495
pub batch_size: usize,
9596
}
9697

98+
/// Extension trait to expose anchors in a public-friendly way
99+
trait TxGraphExt {
100+
fn iter_anchors_ext(
101+
&self,
102+
) -> Box<dyn Iterator<Item = ((Txid, BlockHash), ConfirmationBlockTime)> + '_>;
103+
}
104+
105+
impl TxGraphExt for TxGraph<ConfirmationBlockTime> {
106+
fn iter_anchors_ext(
107+
&self,
108+
) -> Box<dyn Iterator<Item = ((Txid, BlockHash), ConfirmationBlockTime)> + '_> {
109+
Box::new(
110+
self.full_txs().flat_map(move |tx_node| {
111+
tx_node.anchors.iter().map(move |anchor| {
112+
let block_id = anchor.block_id;
113+
((tx_node.txid, block_id.hash), anchor.clone())
114+
})
115+
}),
116+
)
117+
}
118+
}
119+
97120
fn main() -> anyhow::Result<()> {
98121
let example_cli::Init {
99122
args,
@@ -125,6 +148,13 @@ fn main() -> anyhow::Result<()> {
125148
};
126149

127150
let client = BdkElectrumClient::new(electrum_cmd.electrum_args().client(network)?);
151+
152+
// Lock the graph so we can safely borrow data from it,
153+
// and extract all anchor data in a public-friendly format using the extension trait.
154+
// This avoids re-fetching known anchor confirmations from Electrum.
155+
let g = graph.lock().unwrap();
156+
let anchors = g.graph().iter_anchors_ext();
157+
client.populate_anchor_cache(anchors);
128158

129159
// Tell the electrum client about the txs we've already got locally so it doesn't re-download
130160
// them

0 commit comments

Comments
 (0)