Repository navigation
fix(sdk): do not ban nodes when the SDK has no context provider - #5668
llbartekll wants to merge 4 commits into
Conversation
A proved fetch on an SDK without a context provider fails with `drive_proof_verifier::Error::ContextProviderNotSet` after the node has answered. `CanRetry for Error` treated every `Error::Proof` as retryable, so the retry loop banned the node that answered and sent the request to the next one, banning each healthy node in turn for a fault in the SDK's own setup. Carve that one variant out of `can_retry`: the request fails on the first answer, is not sent elsewhere and bans no node. The error keeps its `Proof` shape, so `cannot_verify_answers` and bindings matching on it are unchanged. Closes #5626 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Retry classification and policy tests packages/rs-sdk/src/error.rs |
can_retry returns false for ContextProviderNotSet and QuorumKeyUnavailable caused by a provider configuration error. Tests cover these errors, the retry-exhaustion wrapper, and confirm that other proof errors remain retryable. |
Retry behavior and documentation packages/rs-sdk/src/sync.rs, packages/rs-sdk/src/sdk.rs |
A sync test verifies that retry returns the missing-provider error after one call without banning the responding node. SDK documentation describes the context-provider failure behavior. |
Priority:
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers: shumkov, thepastaclaw
Merge Risk: 
Minimal · up to 332b5
-
Requests without a context provider fail without banning healthy nodes. No merge-blocking risk was identified.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Title check
-
Explanation
The title names the fix and its scope: nodes are no longer banned when the SDK has no context provider. The changeset matches this. Error::can_retry now returns false for Proof(ContextProviderNotSet), the retry path leaves the responding node unbanned, and tests cover both behaviors. The title is short, single-sentence, and specific, and it follows the conventional fix(sdk): form.
Full details: Linked Issues check
-
Explanation
Issue
#5626requiresContextProviderNotSetto be local, non-retryable, and unable to ban a node.CanRetry for Errornow returns false forError::Proof(ContextProviderNotSet). The sync test verifies one attempt, no failover, and no ban for the answering node. The error test also verifies that other proof errors remain retryable. The added documentation describes the behavior.
Full details: Out of Scope Changes check
-
Explanation
The changes remain connected to issue
#5626. The additionalContextProviderError::Configcarve-out covers the same local context-provider setup fault. The tests cover retry classification and node-ban behavior. The SDK documentation change explains the affected proof-parsing behavior. No unrelated change is shown in the reviewed PR evidence.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 3 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
|
🔍 Review in progress — actively reviewing now (commit 332b511) · triage: normal |
…rovider-not-set-no-ban
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 1 + Phase 2
The change correctly prevents retries and responder bans for the exact ContextProviderNotSet failure, and the relevant CI checks are successful. However, the same SDK-local setup fault can surface as Proof(QuorumKeyUnavailable { error: ContextProviderError::Config(_) }), which the existing classification already identifies as unable to verify any answer; the new wildcard still retries and bans nodes for that case.
🟡 1 suggestion(s) | 💬 1 nitpick(s)
Review provenance
Source: reviewer 1: glm-5.3-flash (agent: phase1-reviewer, role: general); reviewer 2: glm-5.3-flash (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
lowbygpt-6.1-sol(effort low) — This is a small, well-contained Rust SDK retry-policy change with focused tests that narrowly exempt one local configuration error while preserving existing retry behavior for sibling proof failures. - Phase 1 reviewers:
glm-5.3-flash— general (completed, effort high); agentphase1-reviewer,glm-5.3-flash— rust-quality (completed, effort high); agentphase1-reviewer - Phase 1 model:
glm-5.3-flash— zai quota: 5h 97% left, weekly 90% left; passed overgemini-3.8-flash-high(antigravity quota lookup failed) - Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort medium); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-sdk/src/error.rs`:
- [SUGGESTION] packages/rs-sdk/src/error.rs:530-534: QuorumKeyUnavailable with a Config error still retries and bans nodes for a local setup failure
The new carve-out handles ContextProviderNotSet, but the same local-setup failure can occur when a configured context provider cannot supply quorum keys and returns ContextProviderError::Config. The SDK's own cannot_verify_answers classification already treats Proof(QuorumKeyUnavailable { error: Config(_) }) as a setup that cannot verify any answer. In this path verify_fetching_quorum_key preserves the error as Error::Proof, so it reaches the Error::Proof(_) => true arm; the retry loop then bans the responding node and tries another one even though no node's answer can be verified. Add this sibling shape to the non-retryable arm and cover it with a regression test.
- [NITPICK] packages/rs-sdk/src/error.rs:699: The exhaustion-wrapper assertion does not test propagation of the inner retry classification
Error::NoAvailableAddressesToRetry is matched by the fallback arm in can_retry and is therefore non-retryable for every inner error. The assertion is correct, but it does not verify that ContextProviderNotSet remains non-retryable through wrapper recursion, because can_retry does not recurse into this wrapper. Clarify that the assertion pins the wrapper's independent non-retryable behavior so future changes do not mistake it for coverage of inner-error propagation.
|
Bots are done — your move: post |
A context provider that answers every quorum key request with ContextProviderError::Config (the WASM context without a trusted context, for one) is the same SDK-local setup fault as having no provider at all: cannot_verify_answers already says so. Classify it non-retryable too, so the retry loop neither bans the responder nor asks another node whose answer could not be verified either. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Re-review — Final validation — Phase 1 + Phase 2
The PR correctly prevents missing-provider and quorum-key configuration failures from retrying or banning responding nodes, and the prior review findings are fixed. One sibling local setup failure remains: a provider Config error returned while loading token configuration is wrapped as Proof(ContextProviderError(Config(_))) and still follows the blanket retry-and-ban path. CI checks for the reviewed head are still pending, with no reported code failures.
🟡 1 suggestion(s)
Review provenance
Source: reviewer 1: glm-5.3-flash (agent: phase1-reviewer, role: general); reviewer 2: glm-5.3-flash (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
lowbygpt-6.1-sol(effort low) — This is a small, well-contained Rust SDK retry-policy change with focused tests, and its correctness is straightforward to verify without affecting consensus, funds, cryptography, or storage. - Phase 1 reviewers:
glm-5.3-flash— general (completed, effort high); agentphase1-reviewer,glm-5.3-flash— rust-quality (completed, effort high); agentphase1-reviewer - Phase 1 model:
glm-5.3-flash— zai quota: 5h 94% left, weekly 90% left; passed overgemini-3.8-flash-high(antigravity quota lookup failed) - Fresh final gate: an independent Phase-2 review ran after iterative findings were reconciled
- Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— general (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort medium); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort medium); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-sdk/src/error.rs`:
- [SUGGESTION] packages/rs-sdk/src/error.rs:534-538: Provider Config errors from token-configuration lookup still retry and ban nodes
The new carve-out handles ContextProviderNotSet and QuorumKeyUnavailable carrying ContextProviderError::Config, but a Config error returned by another context-provider callback has a different verifier shape. In token_perpetual_distribution_last_claim.rs, get_token_configuration(...) uses ?, which produces drive_proof_verifier::Error::ContextProviderError(ContextProviderError::Config(_)); the SDK conversion preserves that as Error::Proof(...), so it reaches Error::Proof(_) => true here. A locally misconfigured provider can therefore ban each healthy responder and retry requests that no other node can make verifiable. Add this sibling shape to the non-retryable classification and add the corresponding shape to cannot_verify_answers so protocol-version refusal classification remains consistent.
Out-of-scope follow-up suggestions (1)
These are valid observations, but they are outside this PR's scope and should be handled in separate issues or author/maintainer-requested PRs rather than blocking this review.
- Platform activation-height Config errors lose their typed local-setup attribution — The total-credits proof path converts get_platform_activation_height Config errors into a string-valued MissingContextRequirement drive error before the SDK sees them, so the SDK cannot apply the same typed non-retryable classification. This is a concrete related issue, but preserving the provider error requires a change in rs-drive-proof-verifier rather than this SDK-only PR.
- Follow-up: Track a follow-up in rs-drive-proof-verifier to preserve ContextProviderError through the MissingContextRequirement mapping, then extend the SDK classification once the typed shape is available.
|
Bots are done — your move: post |
…rovider-not-set-no-ban # Conflicts: # packages/rs-sdk/src/error.rs
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
|
/self-reviewed |
Issue being fixed or feature implemented
Closes #5626.
A proved fetch on an SDK built without a context provider fails with
drive_proof_verifier::Error::ContextProviderNotSet. That error is raised inSdk::parse_proof_with_metadata_and_proof, after the node has answered, so it reaches the retry loop wrapped in anExecutionErrorthat names the node.CanRetry for Errortreated everyError::Proofas retryable, and a retryable error bans its responder (update_address_ban_status) before the request moves to the next node. An SDK with a local setup fault therefore banned each healthy node it asked and failed only when it ran out of them.What was done?
impl CanRetry for Error:Error::Proof(ContextProviderNotSet)is no longer retryable. The request fails on the first answer, is not sent to another node, and bans none.Proofshape.Error::cannot_verify_answersalready classifies it as the SDK's own setup, and bindings that match onProofare unchanged. Re-mapping it toError::ConfiginFrom<drive_proof_verifier::Error>was considered and rejected: it changes the public error shape for no gain.parse_proof_with_metadata_and_proof's doc, next to the existing note on howStaleNodeError::ProtocolVersionis retried.How Has This Been Tested?
error::tests::should_not_retry_a_proved_fetch_without_a_context_provider: the variant is non-retryable, also underNoAvailableAddressesToRetry; siblingProoffailures (QuorumKeyUnavailable,ProtocolError) stay retryable, so the carve-out is narrow.sync::test::should_fail_without_banning_when_the_context_provider_is_not_set: drivesretryover two nodes withretries: Some(3); the closure runs once, the error comes back asProof(ContextProviderNotSet), and the node that answered is still live with nobanned_until.cargo test -p dash-sdk --lib: 531 passed. Note: on currentv5.1-devthe lib test target does not compile because fix(platform-wallet): retry an oversized InstantSend asset-lock transition with a ChainLock proof #5460 added aplatform_versionargument tobroadcast_with_retrieswithout updatingaddress_nonce_tests.rs; fix(sdk): pass the platform version in the address nonce broadcast tests #5667 fixes that, and the run above applied its diff locally. This PR does not touch that file.cargo clippy -p dash-sdk --libandcargo fmt --all -- --checkclean.Breaking Changes
None.
Checklist:
structure.rs, regeneratedgrovedb-structure.json, and checked the structure viewer link posted on this pull requestFor repository code-owners and collaborators only
🤖 Generated with Claude Code
PR Hygiene ·
332b511/skip-botsproceeds without the ones not yet reportedrust-sdk(packages/rs-sdk/src/error.rs,packages/rs-sdk/src/sdk.rs,packages/rs-sdk/src/sync.rs) — lklimek or shumkovWhen every merge requirement is met, the
PR Hygienecheck passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.Summary by CodeRabbit