Skip to content

fix: clearer readiness while node is still syncing#3894

Open
iho wants to merge 1 commit into
mimblewimble:stagingfrom
iho:fix/api-stratum-ready-after-sync
Open

fix: clearer readiness while node is still syncing#3894
iho wants to merge 1 commit into
mimblewimble:stagingfrom
iho:fix/api-stratum-ready-after-sync

Conversation

@iho

@iho iho commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Fixes #3546.

API and stratum used to accept connections immediately while the chain was still initialising/syncing. Wallets then saw opaque NotFound / null decode errors (e.g. on get_pmmr_indices); miners connected only to get “node is syncing” job failures.

Changes

Area Behaviour
Stratum Do not bind/listen until !sync_state.is_syncing(); set is_running only then
Foreign API get_pmmr_indices / get_outputs / get_unspent_outputs return Error::Unavailable (“node is still syncing…”) while syncing
REST Map UnavailableHTTP 503
Status / tip / version Unchanged so monitoring still works during sync
PMMR map errors Surface the real chain error instead of empty NotFound

Test plan

  • cargo test -p grin_api --lib -- --test-threads=1 (includes ensure_not_syncing_*)
  • cargo test -p grin_servers --lib mining::stratumserver -- --test-threads=1
  • Start node mid-sync: wallet get_pmmr_indices should report syncing / 503, not null NotFound
  • Stratum port should not accept until sync completes

- Stratum: wait for sync to finish before accepting miner connections
  so clients are not confused by early "syncing" / failed job responses.
- Foreign API: return Error::Unavailable (HTTP 503) for wallet-facing
  queries (get_pmmr_indices, get_outputs, get_unspent_outputs) while
  syncing, instead of misleading NotFound/null.
- Preserve descriptive errors when height→PMMR mapping fails.

Addresses mimblewimble#3546.
@wiesche89
wiesche89 self-requested a review July 12, 2026 07:32

@wiesche89 wiesche89 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.

The readiness direction makes sense, but the wallet still sees null decode errors because its JSON-RPC client only reads result["Ok"]. The new 503 mapping is not reached by these methods. I think the actual wallet/RPC response should be tested before this is considered fixed.

Comment thread api/src/foreign.rs
end_block_height: Option<u64>,
) -> Result<OutputListing, Error> {
// Wallet scan/info hits this early; return a clear signal while syncing (#3546).
ensure_not_syncing(&self.sync_state)?;

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.

The current grin-wallet client only deserializes result["Ok"] and ignores result["Err"]. This therefore still becomes null and produces the same OutputListing decode error. Could we test this against the actual wallet response handling?

Comment thread api/src/web.rs
Error::Argument(msg) => response(StatusCode::BAD_REQUEST, msg),
Error::RequestError(msg) => response(StatusCode::BAD_REQUEST, msg),
Error::NotFound => response(StatusCode::NOT_FOUND, "".into()),
Error::Unavailable(msg) => response(StatusCode::SERVICE_UNAVAILABLE, msg),

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.

None of the changed endpoints reaches this REST path. /v2/foreign still returns HTTP 200. Is the 503 mapping meant to be used elsewhere?

.map_err(|_| Error::NotFound)?;
.map_err(|e| {
// Prefer a descriptive error over empty NotFound (wallet misreports null).
Error::Argument(format!(

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.

Internal store or PMMR errors can also reach this path. Could we avoid reporting all chain errors as bad arguments?

});

// We have started
// We have started (only after sync so is_running matches actual readiness).

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.

The listener binds in the spawned thread, so this flag can still become true before bind succeeds. Could startup report success before we mark Stratum as running?

let handler = Arc::new(Handler::from_stratum(&self));
let h = handler.clone();

// Wait until the node has finished syncing before accepting miner connections

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.

Could we shorten this to describe the current behavior and leave the issue history in the PR?

Comment thread api/src/foreign.rs
start_block_height: u64,
end_block_height: Option<u64>,
) -> Result<OutputListing, Error> {
// Wallet scan/info hits this early; return a clear signal while syncing (#3546).

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.

Could we shorten this to describe the current behavior and leave the issue history in the PR?

Comment thread api/src/foreign.rs
include_proof: Option<bool>,
_include_merkle_proof: Option<bool>,
) -> Result<Vec<OutputPrintable>, Error> {
ensure_not_syncing(&self.sync_state)?;

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.

The current grin-wallet client only reads result["Ok"], so these Err responses still become null and produce decode errors. Could we test all three methods through the actual wallet RPC handling?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants