Skip to content

Commit d8be40c

Browse files
committed
Merge #2148: chain 0.23.x: Fix panic in scan loop and update msrv and esplora-client
2ee48d7 fix(esplora): Bump `esplora-client` to `0.12.3` (志宇) af6791f ci: Fix `ci/pin-msrv.sh` (志宇) fb3e169 ci: Fix pin msrv for 1.75.0 (志宇) 8d2ca9b fix: remove panic from stop gap scan loop (Matthew) Pull request description: ### Description Backport of #2053, #2136. Also fixes CI MSRV issues. Replaces #2147 - Purely MSRV fixes still resulted in CI failure due to clippy. Replaces #2141 - Might as well include the whole PR backport. ### Changelog notice ```md Fixed: - Avoid a panic in the Esplora stop‑gap scan loop by tracking consecutive unused scripts to compute the gap boundary. - Bump `esplora_client` to `0.12.3` so that the `.get_block_infos` method is always available. ``` ### Checklists #### All Submissions: * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) ACKs for top commit: luisschwab: ACK 2ee48d7 oleonardolima: ACK 2ee48d7 Tree-SHA512: 0f183e2b5ffc6629298f960f22e95020df58da98171c69e880afab5d57f337af240ff7ad97244f3f052d3b1a3fdd8a91543b5a943eeac2234de02672fc94d3f2
2 parents 1a77475 + 2ee48d7 commit d8be40c

File tree

5 files changed

+53
-30
lines changed

5 files changed

+53
-30
lines changed

.github/workflows/cont_integration.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ jobs:
5858
cargo update -p rayon-core --precise "1.12.1"
5959
cargo update -p time --precise "0.3.41"
6060
cargo update -p proptest --precise "1.8.0"
61+
cargo update -p "getrandom@0.4.2" --precise "0.2.17"
6162
- name: Pin dependencies for MSRV
6263
if: matrix.rust.version == '1.63.0'
6364
run: ./ci/pin-msrv.sh

ci/pin-msrv.sh

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
set -x
44
set -euo pipefail
55

6-
# Pin dependencies for MSRV
6+
# Pin dependencies for MSRV (1.63.0)
77

88
# To pin deps, switch toolchain to MSRV and execute the below updates
99

@@ -17,22 +17,43 @@ cargo update -p proptest --precise "1.2.0"
1717
cargo update -p url --precise "2.5.0"
1818
cargo update -p tokio --precise "1.38.1"
1919
cargo update -p reqwest --precise "0.12.4"
20+
cargo update -p native-tls --precise "0.2.13"
2021
cargo update -p security-framework-sys --precise "2.11.1"
2122
cargo update -p csv --precise "1.3.0"
2223
cargo update -p unicode-width --precise "0.1.13"
23-
cargo update -p native-tls --precise "0.2.13"
2424
cargo update -p flate2 --precise "1.0.35"
2525
cargo update -p bzip2-sys --precise "0.1.12"
2626
cargo update -p ring --precise "0.17.12"
2727
cargo update -p once_cell --precise "1.20.3"
2828
cargo update -p base64ct --precise "1.6.0"
2929
cargo update -p minreq --precise "2.13.2"
30+
cargo update -p tracing --precise "0.1.40"
3031
cargo update -p tracing-core --precise "0.1.33"
31-
cargo update -p webpki-roots@1.0.4 --precise "1.0.1"
32+
cargo update -p "webpki-roots@1.0.6" --precise "1.0.1"
3233
cargo update -p rayon --precise "1.10.0"
3334
cargo update -p rayon-core --precise "1.12.1"
34-
cargo update -p socket2@0.6.1 --precise "0.5.10"
3535
cargo update -p quote --precise "1.0.41"
3636
cargo update -p syn --precise "2.0.106"
3737
cargo update -p openssl --precise "0.10.73"
3838
cargo update -p openssl-sys --precise "0.9.109"
39+
cargo update -p "getrandom@0.4.2" --precise "0.2.17"
40+
cargo update -p serde_json --precise "1.0.138"
41+
cargo update -p ryu --precise "1.0.18"
42+
cargo update -p futures --precise "0.3.30"
43+
cargo update -p futures-executor --precise "0.3.31"
44+
cargo update -p futures-util --precise "0.3.31"
45+
cargo update -p futures-macro --precise "0.3.31"
46+
cargo update -p futures-channel --precise "0.3.31"
47+
cargo update -p futures-core --precise "0.3.31"
48+
cargo update -p futures-io --precise "0.3.31"
49+
cargo update -p futures-sink --precise "0.3.31"
50+
cargo update -p futures-task --precise "0.3.31"
51+
cargo update -p proc-macro2 --precise "1.0.92"
52+
cargo update -p log --precise "0.4.22"
53+
cargo update -p itoa --precise "1.0.11"
54+
cargo update -p anyhow --precise "1.0.86"
55+
cargo update -p unicode-ident --precise "1.0.13"
56+
cargo update -p hyper-util --precise "0.1.6"
57+
cargo update -p pin-project --precise "1.1.5"
58+
cargo update -p pin-project-internal --precise "1.1.5"
59+
cargo update -p "rustls@0.23.37" --precise "0.23.26"

crates/esplora/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ workspace = true
1616

1717
[dependencies]
1818
bdk_core = { path = "../core", version = "0.6.1", default-features = false }
19-
esplora-client = { version = "0.12.1", default-features = false }
19+
esplora-client = { version = "0.12.3", default-features = false }
2020
async-trait = { version = "0.1.66", optional = true }
2121
futures = { version = "0.3.26", optional = true }
2222

crates/esplora/src/async_ext.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,10 @@ async fn fetch_latest_blocks<S: Sleeper>(
184184
client: &esplora_client::AsyncClient<S>,
185185
) -> Result<BTreeMap<u32, BlockHash>, Error> {
186186
Ok(client
187-
.get_blocks(None)
187+
.get_block_infos(None)
188188
.await?
189189
.into_iter()
190-
.map(|b| (b.time.height, b.id))
190+
.map(|b| (b.height, b.id))
191191
.collect())
192192
}
193193

@@ -314,8 +314,11 @@ where
314314
type TxsOfSpkIndex = (u32, Vec<esplora_client::Tx>, HashSet<Txid>);
315315

316316
let mut update = TxUpdate::<ConfirmationBlockTime>::default();
317-
let mut last_index = Option::<u32>::None;
318317
let mut last_active_index = Option::<u32>::None;
318+
// Use consecutive_unused so unused count drives stop gap.
319+
let mut consecutive_unused = 0usize;
320+
// Treat stop_gap = 0 as 1 while preserving original semantics for other values.
321+
let gap_limit = stop_gap.max(1);
319322

320323
loop {
321324
let handles = keychain_spks
@@ -352,8 +355,10 @@ where
352355
}
353356

354357
for (index, txs, evicted) in handles.try_collect::<Vec<TxsOfSpkIndex>>().await? {
355-
last_index = Some(index);
356-
if !txs.is_empty() {
358+
if txs.is_empty() {
359+
consecutive_unused = consecutive_unused.saturating_add(1);
360+
} else {
361+
consecutive_unused = 0;
357362
last_active_index = Some(index);
358363
}
359364
for tx in txs {
@@ -368,13 +373,7 @@ where
368373
.extend(evicted.into_iter().map(|txid| (txid, start_time)));
369374
}
370375

371-
let last_index = last_index.expect("Must be set since handles wasn't empty.");
372-
let gap_limit_reached = if let Some(i) = last_active_index {
373-
last_index >= i.saturating_add(stop_gap as u32)
374-
} else {
375-
last_index + 1 >= stop_gap as u32
376-
};
377-
if gap_limit_reached {
376+
if consecutive_unused >= gap_limit {
378377
break;
379378
}
380379
}
@@ -599,7 +598,10 @@ mod test {
599598
let res = chain_update(&client, &latest_blocks, &cp, &anchors).await;
600599
use esplora_client::Error;
601600
assert!(
602-
matches!(*res.unwrap_err(), Error::HeaderHashNotFound(hash) if hash == genesis_hash),
601+
matches!(
602+
*res.unwrap_err(),
603+
Error::HeaderHashNotFound(hash) if hash == genesis_hash
604+
),
603605
"`chain_update` should error if it can't connect to the local CP",
604606
);
605607

crates/esplora/src/blocking_ext.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,9 @@ fn fetch_latest_blocks(
170170
client: &esplora_client::BlockingClient,
171171
) -> Result<BTreeMap<u32, BlockHash>, Error> {
172172
Ok(client
173-
.get_blocks(None)?
173+
.get_block_infos(None)?
174174
.into_iter()
175-
.map(|b| (b.time.height, b.id))
175+
.map(|b| (b.height, b.id))
176176
.collect())
177177
}
178178

@@ -282,8 +282,11 @@ fn fetch_txs_with_keychain_spks<I: Iterator<Item = Indexed<SpkWithExpectedTxids>
282282
type TxsOfSpkIndex = (u32, Vec<esplora_client::Tx>, HashSet<Txid>);
283283

284284
let mut update = TxUpdate::<ConfirmationBlockTime>::default();
285-
let mut last_index = Option::<u32>::None;
286285
let mut last_active_index = Option::<u32>::None;
286+
// Use consecutive_unused so unused count drives stop gap.
287+
let mut consecutive_unused = 0usize;
288+
// Treat stop_gap = 0 as 1 while preserving original semantics for other values.
289+
let gap_limit = stop_gap.max(1);
287290

288291
loop {
289292
let handles = keychain_spks
@@ -321,8 +324,10 @@ fn fetch_txs_with_keychain_spks<I: Iterator<Item = Indexed<SpkWithExpectedTxids>
321324

322325
for handle in handles {
323326
let (index, txs, evicted) = handle.join().expect("thread must not panic")?;
324-
last_index = Some(index);
325-
if !txs.is_empty() {
327+
if txs.is_empty() {
328+
consecutive_unused = consecutive_unused.saturating_add(1);
329+
} else {
330+
consecutive_unused = 0;
326331
last_active_index = Some(index);
327332
}
328333
for tx in txs {
@@ -337,13 +342,7 @@ fn fetch_txs_with_keychain_spks<I: Iterator<Item = Indexed<SpkWithExpectedTxids>
337342
.extend(evicted.into_iter().map(|txid| (txid, start_time)));
338343
}
339344

340-
let last_index = last_index.expect("Must be set since handles wasn't empty.");
341-
let gap_limit_reached = if let Some(i) = last_active_index {
342-
last_index >= i.saturating_add(stop_gap as u32)
343-
} else {
344-
last_index + 1 >= stop_gap as u32
345-
};
346-
if gap_limit_reached {
345+
if consecutive_unused >= gap_limit {
347346
break;
348347
}
349348
}

0 commit comments

Comments
 (0)