Skip to content

Gate backend-specific full_scan options - #367

Open
emma31-dev wants to merge 1 commit into
bitcoindevkit:masterfrom
emma31-dev:fix/full-scan-backend-options
Open

emma31-dev wants to merge 1 commit into
bitcoindevkit:masterfrom
emma31-dev:fix/full-scan-backend-options

Conversation

@emma31-dev

@emma31-dev emma31-dev commented Oct 25, 2026 •

Copy link
Copy Markdown

Description

Make full_scan options reflect backend support: gate --scan-stop-gap to Electrum/Esplora builds and make Esplora's --parallel-request an optional override of the wallet-configured request count. Related to #340 .

Notes to the reviewers

The RPC backend still scans blocks through Emitter and does not use stop_gap as a lookahead. This change removes the option from RPC-only builds but does not make RPC discover funds beyond its current lookahead. In builds with multiple backend features enabled, the compile-time flag may still be available when the wallet is configured for RPC.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

@github-project-automation github-project-automation Bot moved this to Todo in BDK-CLI Oct 25, 2026
@emma31-dev
emma31-dev force-pushed the fix/full-scan-backend-options branch from 2fc5eb8 to 922dd64 Compare October 25, 2026 15:55
@emma31-dev emma31-dev changed the title Allow overriding Esplora scan parallelism Gate backend-specific full_scan options Oct 25, 2026
@Olorunshogo

Olorunshogo commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

I tested this locally against #340 (regtest, Core v32.1.0, funds only at external index 30, RPC wallet):

Build full_scan full_scan --scan-stop-gap 100
--features rpc exit 0, balance 0 rejected: unexpected argument '--scan-stop-gap'
--features rpc,esplora exit 0, balance 0 accepted, exit 0, balance 0

Rejecting the flag in RPC-only builds is a nice improvement over silently ignoring it. In a multi-backend build, though, the flag is still accepted and ignored when the wallet uses RPC, because the gate is compile-time while the backend is picked at runtime from the wallet config. A runtime check on the client type would cover that case.

A few smaller things:

Full reproduction details are in my comment on #340.

@emma31-dev

Copy link
Copy Markdown
Author

Thanks for bringing this up I'll make the change soon

@emma31-dev
emma31-dev force-pushed the fix/full-scan-backend-options branch from 14a82b5 to f2c493e Compare November 6, 2026 13:20

@Olorunshogo Olorunshogo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested b929aa1 against master (regtest, Core v32.1.0, Esplora electrs, built with rpc,esplora,electrum).

The runtime check works: an RPC wallet now rejects --scan-stop-gap and --parallel-request with a clear error instead of silently ignoring them, and Electrum rejects --parallel-request. Esplora and Electrum scans behave the same as on master, including --scan-stop-gap 40 recovering funds at index 30. Clippy is clean with rpc,esplora,electrum and with rpc only.

Left two inline comments: the STOP_GAP env var now breaks RPC scans, and the default of 20 no longer shows in --help.

Smaller: the PR description still says the flag may be available for RPC wallets in multi-backend builds, which the runtime check now prevents, and the branch has a merge commit.

Happy to ACK once the two inline points are addressed.

Comment thread src/handlers/online.rs Outdated
#[clap(long, default_value = "5")]
pub parallel_request: usize,
#[cfg(any(feature = "electrum", feature = "esplora"))]
#[arg(env = "STOP_GAP", long = "scan-stop-gap")]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this still reads STOP_GAP from the environment, an RPC full_scan fails when STOP_GAP is set, even if --scan-stop-gap isn't passed. I reproduced it: with STOP_GAP=50 exported, an RPC wallet errors with "--scan-stop-gap is only supported by the electrum and esplora backends", while the same scan works on master.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I can gate the env parsing. What do you suggest I do here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'll include it in the error message

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b6e54bf, thanks!

Comment thread src/handlers/online.rs Outdated
client.populate_tx_cache(wallet.tx_graph().full_txs().map(|tx_node| tx_node.tx));
let update = client.full_scan(request, self.stop_gap, *batch_size, false)?;
let update =
client.full_scan(request, self.stop_gap.unwrap_or(20), *batch_size, false)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With default_value = "20" gone, full_scan --help no longer shows [default: 20], and 20 is now repeated here and in the Esplora branch. A shared constant like DEFAULT_STOP_GAP, mentioned in the doc comment, would keep the default visible and in one place.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of this yesterday thanks for bringing this up

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b6e54bf, thanks!

@emma31-dev

Copy link
Copy Markdown
Author

@Olorunshogo Thanks for the review. I'll fix the minor issues.

@emma31-dev
emma31-dev force-pushed the fix/full-scan-backend-options branch 2 times, most recently from 797c619 to 0e2f54b Compare November 7, 2026 16:11
@emma31-dev

Copy link
Copy Markdown
Author

@vadim-anfv I would appreciate a review on this when you have the time.

The RPC and CBF backends never use `stop_gap`, so accepting the flag silently
ignored it. Gate the option to the Electrum and Esplora backends and reject it
at runtime for RPC and CBF wallets in multi-backend builds, where the backend is
chosen from the wallet config rather than at compile time.

Read `STOP_GAP` in the handler rather than through clap so that a globally
exported value no longer turns an RPC or CBF scan into an error when the flag
was never passed, while supported backends keep the environment behaviour.

Keep the default of 20 in one place (`DEFAULT_STOP_GAP`) and document it, with
the env var, in `--help`.

Related to bitcoindevkit#340.
@emma31-dev
emma31-dev force-pushed the fix/full-scan-backend-options branch from 0e2f54b to b6e54bf Compare November 10, 2026 11:21
@codecov

codecov Bot commented Nov 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 47.22222% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.89%. Comparing base (5558555) to head (b6e54bf).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/handlers/online.rs 47.22% 19 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #367      +/-   ##
==========================================
- Coverage   60.00%   59.89%   -0.12%     
==========================================
  Files          25       25              
  Lines        4736     4770      +34     
==========================================
+ Hits         2842     2857      +15     
- Misses       1894     1913      +19     
Flag Coverage Δ
rust 59.89% <47.22%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vadim-anfv vadim-anfv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK b6e54bf

Tested with no node running, so a scan fails at the connection and the gate is the only thing under test.

Setup, on an rpc,electrum,esplora build:

w() {
  cargo run -q --features rpc,electrum,esplora -- \
    -n regtest -d /tmp/bdk367 wallet -w rpc "$@"
}

w config -f \
  -e 'wpkh(tpubDDnGNapGEY6AZAdQbfRJgMg9fvz8pUBrLwvyvUqEgcUfgzM6zc2eVK4vY9x9L5FJWdX8WumXuLEDV5zDZnTfbn87vLe9XceCFwTu9so9Kks/0/*)' \
  -c rpc --database-type sqlite -u http://127.0.0.1:18443

The flag is present:

$ w full_scan --help
Options:
      --scan-stop-gap <STOP_GAP>
          Stop searching addresses for transactions after finding an unused gap of this length. Only available with the `electrum` and `esplora` backends. When the flag is omitted, the `STOP_GAP` environment variable is read if it is set. [default: 20]

An RPC wallet rejects it:

$ w full_scan --scan-stop-gap 100
Error: Generic error: `--scan-stop-gap` is only supported by the electrum and esplora backends

Without the flag the same wallet gets past the check:

$ w full_scan
Error: RPC error: JSON-RPC error: transport error: Couldn't connect to host: Connection refused (os error 111)

In an rpc only build the flag does not exist at all:

$ cargo run -q --no-default-features --features rpc,sqlite -- \
    -n regtest -d /tmp/bdk367 wallet -w rpc full_scan --scan-stop-gap 100
error: unexpected argument '--scan-stop-gap' found

Usage: bdk-cli wallet --wallet <WALLET> full_scan [OPTIONS]

For more information, try '--help'.

Thanks @Olorunshogo for the thorough testing and review. I did not test myself that the stop gap still reaches the Electrum and Esplora clients after the refactor.

@emma31-dev please update the PR description, it still describes the first version: the flag available for RPC wallets in multi-backend builds, and --parallel-request becoming an override. Neither matches the diff now.

Comment thread src/handlers/online.rs
Comment on lines +176 to +182
#[cfg(any(feature = "electrum", feature = "esplora"))]
if self.stop_gap.is_some() {
return Err(Error::Generic(
"`--scan-stop-gap` is only supported by the electrum and esplora backends"
.into(),
));
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the rejection block is identical in the RPC and CBF arms, and each copy carries its own #[cfg(any(feature = "electrum", feature = "esplora"))]. A small fn reject_stop_gap(&self) -> Result<(), Error> next to stop_gap() would leave one cfg instead of three and one copy of the message.

@Olorunshogo Olorunshogo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK b6e54bf

Thanks for working through the env var issue, moving the STOP_GAP read into stop_gap() solves it cleanly.

Tested against master on regtest (Core v32.1.0, Esplora electrs, built with rpc,esplora,electrum).

Non-blocking:

  • STOP_GAP=0 is accepted and scans nothing, while the error says "must be a positive integer". Same as master, but rejecting 0 or saying "non-negative" would match.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants