Skip to content

Commit caa173d

Browse files
Support all chain sources for wallet birthday block hash lookup
Extend get_block_hash_by_height to work with Esplora and Electrum in addition to bitcoind. Esplora uses its native get_block_hash API. Electrum uses block_header_raw and extracts the hash from the header. For Electrum, if the runtime client hasn't started yet (called during build), a temporary connection is created for the lookup.
1 parent 172b44e commit caa173d

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/chain/electrum.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,28 @@ impl ElectrumChainSource {
8989
self.electrum_runtime_status.write().unwrap().stop();
9090
}
9191

92+
pub(super) async fn get_block_hash_by_height(
93+
&self, height: u32,
94+
) -> Result<bitcoin::BlockHash, ()> {
95+
// Try the runtime client if started, otherwise create a temporary connection.
96+
let status = self.electrum_runtime_status.read().unwrap();
97+
if let Some(client) = status.client() {
98+
drop(status);
99+
return client.get_block_hash_by_height(height);
100+
}
101+
drop(status);
102+
103+
// Runtime not started yet (called during build). Use a temporary client.
104+
let config = ElectrumConfigBuilder::new()
105+
.timeout(Some(self.sync_config.timeouts_config.per_request_timeout_secs))
106+
.build();
107+
let client = ElectrumClient::from_config(&self.server_url, config).map_err(|_| ())?;
108+
let header_bytes = client.block_header_raw(height as usize).map_err(|_| ())?;
109+
let header: bitcoin::block::Header =
110+
bitcoin::consensus::deserialize(&header_bytes).map_err(|_| ())?;
111+
Ok(header.block_hash())
112+
}
113+
92114
pub(crate) async fn sync_onchain_wallet(
93115
&self, onchain_wallet: Arc<Wallet>,
94116
) -> Result<(), Error> {
@@ -420,6 +442,14 @@ impl ElectrumRuntimeClient {
420442
})
421443
}
422444

445+
fn get_block_hash_by_height(&self, height: u32) -> Result<bitcoin::BlockHash, ()> {
446+
let header_bytes =
447+
self.electrum_client.block_header_raw(height as usize).map_err(|_| ())?;
448+
let header: bitcoin::block::Header =
449+
bitcoin::consensus::deserialize(&header_bytes).map_err(|_| ())?;
450+
Ok(header.block_hash())
451+
}
452+
423453
async fn sync_confirmables(
424454
&self, confirmables: Vec<Arc<dyn Confirm + Sync + Send>>,
425455
) -> Result<(), Error> {

src/chain/esplora.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ impl EsploraChainSource {
7474
}
7575
}
7676

77+
pub(super) async fn get_block_hash_by_height(
78+
&self, height: u32,
79+
) -> Result<bitcoin::BlockHash, ()> {
80+
self.esplora_client.get_block_hash(height).await.map_err(|_| ())
81+
}
82+
7783
pub(super) async fn sync_onchain_wallet(
7884
&self, onchain_wallet: Arc<Wallet>,
7985
) -> Result<(), Error> {

src/chain/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,12 @@ impl ChainSource {
224224
let utxo_source = bitcoind_chain_source.as_utxo_source();
225225
utxo_source.get_block_hash_by_height(height).await.map_err(|_| ())
226226
},
227-
_ => Err(()),
227+
ChainSourceKind::Esplora(esplora_chain_source) => {
228+
esplora_chain_source.get_block_hash_by_height(height).await
229+
},
230+
ChainSourceKind::Electrum(electrum_chain_source) => {
231+
electrum_chain_source.get_block_hash_by_height(height).await
232+
},
228233
}
229234
}
230235

0 commit comments

Comments
 (0)