fix(sdk): eagerly bootstrap protocol version before first proof parse#3493
fix(sdk): eagerly bootstrap protocol version before first proof parse#3493QuantumExplorer wants to merge 3 commits intov3.1-devfrom
Conversation
The auto-detect protocol version feature introduced in #3483 updated the cached version only *after* a proof-backed response was successfully parsed. On a fresh auto-detect SDK the first parse therefore used PlatformVersion::latest() as a fallback, so on an older network whose proof interpretation differs from latest() the very first request could fail before the SDK ever got a chance to learn the correct version. Close that bootstrap hole by running a one-shot unproved RPC (CurrentQuorumsInfo) the first time parse_proof_with_metadata_and_proof is invoked, reading metadata.protocol_version from the response, and updating the SDK's cached version before the proof parse runs. A tokio::sync::OnceCell guarantees the bootstrap RPC runs at most once per SDK (and its clones) even under concurrent first calls. Skipped for pinned SDKs (with_version), mock SDKs, and any SDK that has already seen a response. If the bootstrap RPC itself fails the SDK logs a warning and falls back to the previous latest() behaviour so partially-reachable networks still function. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughUpdated Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant SDK
participant OnceCell as OnceCell<br/>(Bootstrap)
participant DAPI
participant MetadataCache
Client->>SDK: parse_proof_with_metadata_and_proof()
SDK->>OnceCell: Check if bootstrap completed
alt First call (OnceCell empty)
OnceCell->>SDK: Bootstrap needed
SDK->>SDK: Check if auto-detect enabled<br/>& cached version == 0
alt Conditions met
SDK->>DAPI: fetch_unproved<br/>CurrentQuorumsInfo
DAPI-->>SDK: metadata with protocol_version
SDK->>MetadataCache: Update cached<br/>protocol_version
SDK->>OnceCell: Mark bootstrap complete
else Conditions not met
SDK->>OnceCell: Mark bootstrap complete<br/>(no-op)
end
else Already bootstrapped
OnceCell-->>SDK: Bootstrap skipped<br/>(cached result)
end
SDK->>Client: Resume proof parsing
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
|
⏳ Review in progress (commit 923c4af) |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/rs-sdk/src/sdk.rs`:
- Around line 357-360: The bootstrap RPC call uses RequestSettings::default()
which ignores the SDK-wide settings and caller overrides; replace that hardcoded
default with the SDK instance's configured RequestSettings (the field on the
client, e.g., self.request_settings or self.settings) and pass that into
CurrentQuorumsInfo::fetch_unproved_with_settings so the call honors
SdkBuilder::with_settings() and the SDK's retry/timeout policy.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c7a31a89-fb63-46a6-af36-cebcad6b41dd
📒 Files selected for processing (2)
.gitignorepackages/rs-sdk/src/sdk.rs
| match CurrentQuorumsInfo::fetch_unproved_with_settings( | ||
| self, | ||
| NoParamQuery {}, | ||
| RequestSettings::default(), |
There was a problem hiding this comment.
Use the SDK’s configured request settings for the bootstrap RPC.
Line 360 hardcodes RequestSettings::default(), so this new pre-parse RPC ignores both the SDK default retry policy and any caller overrides from SdkBuilder::with_settings(). That makes the first proof-backed request run under a different timeout/retry policy than every other SDK call.
Suggested fix
match CurrentQuorumsInfo::fetch_unproved_with_settings(
self,
NoParamQuery {},
- RequestSettings::default(),
+ self.dapi_client_settings,
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| match CurrentQuorumsInfo::fetch_unproved_with_settings( | |
| self, | |
| NoParamQuery {}, | |
| RequestSettings::default(), | |
| match CurrentQuorumsInfo::fetch_unproved_with_settings( | |
| self, | |
| NoParamQuery {}, | |
| self.dapi_client_settings, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/rs-sdk/src/sdk.rs` around lines 357 - 360, The bootstrap RPC call
uses RequestSettings::default() which ignores the SDK-wide settings and caller
overrides; replace that hardcoded default with the SDK instance's configured
RequestSettings (the field on the client, e.g., self.request_settings or
self.settings) and pass that into
CurrentQuorumsInfo::fetch_unproved_with_settings so the call honors
SdkBuilder::with_settings() and the SDK's retry/timeout policy.
|
✅ DashSDKFFI.xcframework built for this PR.
SwiftPM (host the zip at a stable URL, then use): .binaryTarget(
name: "DashSDKFFI",
url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
checksum: "c4e7ddc282704f0a475ba2a8f9f187d52feede046a90605ef3479195aac1590b"
)Xcode manual integration:
|
| { | ||
| // Learn the network protocol version before the first proof parse. | ||
| // No-op after the first successful call (and for pinned / mock SDKs). | ||
| self.ensure_protocol_version_bootstrapped().await; |
There was a problem hiding this comment.
I think calling this function in SdkBuilder::build() will be simpler and (marginally) cheaper.
Summary
Close the bootstrap hole in the auto-detect protocol version feature from #3483.
Before: On a fresh auto-detect SDK the first `parse_proof_with_metadata_and_proof` call uses `PlatformVersion::latest()` as a fallback because no response metadata has been seen yet. On an older network whose proof interpretation differs from `latest()`, the very first proof-backed request fails before the SDK ever learns the correct version. The old doc comment on `parse_proof_with_metadata_and_proof` called this out as a known limitation and told users to pin the version explicitly via `SdkBuilder::with_version()` if they cared.
After: The first time `parse_proof_with_metadata_and_proof` runs on an auto-detect SDK, it transparently kicks off a one-shot `CurrentQuorumsInfo` unproved RPC, reads `metadata.protocol_version` from the response, and updates the SDK's cached version before the proof parse executes. A `tokio::sync::OnceCell` guarantees the bootstrap RPC runs at most once per SDK (and its clones) even under concurrent first calls — subsequent callers wait for the in-flight bootstrap to finish.
Design notes
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Chores
.gitignoreconfiguration.