Skip to content

Commit dacdcd0

Browse files
author
+Sharon
committed
Add populate_anchor_cache method to bdk
1 parent 8d9df97 commit dacdcd0

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

crates/electrum/src/bdk_electrum_client.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use bdk_core::{
77
BlockId, CheckPoint, ConfirmationBlockTime, TxUpdate,
88
};
99
use electrum_client::{ElectrumApi, Error, HeaderNotification};
10+
use std::convert::TryInto;
1011
use std::sync::{Arc, Mutex};
1112

1213
/// We include a chain suffix of a certain length for the purpose of robustness.
@@ -37,6 +38,17 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
3738
}
3839
}
3940

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

examples/example_electrum/src/main.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::io::{self, Write};
22

33
use bdk_chain::{
4-
bitcoin::Network,
4+
bitcoin::{BlockHash, Network, Txid},
55
collections::BTreeSet,
66
indexed_tx_graph,
77
spk_client::{FullScanRequest, SyncRequest},
8-
CanonicalizationParams, ConfirmationBlockTime, Merge,
8+
CanonicalizationParams, ConfirmationBlockTime, Merge, TxGraph,
99
};
1010
use bdk_electrum::{
1111
electrum_client::{self, Client, ElectrumApi},
@@ -94,6 +94,26 @@ pub struct ScanOptions {
9494
pub batch_size: usize,
9595
}
9696

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

127147
let client = BdkElectrumClient::new(electrum_cmd.electrum_args().client(network)?);
128148

149+
// Lock the graph so we can safely borrow data from it,
150+
// and extract all anchor data in a public-friendly format using the extension trait.
151+
// This avoids re-fetching known anchor confirmations from Electrum.
152+
let g = graph.lock().unwrap();
153+
let anchors = g.graph().iter_anchors_ext();
154+
client.populate_anchor_cache(anchors);
155+
129156
// Tell the electrum client about the txs we've already got locally so it doesn't re-download
130157
// them
131158
client.populate_tx_cache(

0 commit comments

Comments
 (0)