Repository navigation
fix(sdk): refuse a non-unique identity V1 request before protocol 14 is proven - #5615
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
|
✅ Final review complete — no blockers (commit f585aa6) · triage: normal |
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 1 + Phase 2
The PR correctly declares protocol 14 as required for V1 non-unique public-key-hash requests while preserving ungated V0 and absent-version behavior. The SDK gate, request delegation, request inventory, and regression tests consistently cover both raw requests and the SDK-selected request path. CI reports the Rust workspace tests and relevant build checks successful, with no in-scope issues found.
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (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: platform-versioning); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
normalbygpt-6.1-sol(effort low) — This is a contained Rust SDK transport-gating fix with meaningful protocol-version behavior and tests, but it does not meet the critical-tier requirement of a large diff changing consensus, cryptography, funds, storage migration, or peer-facing deserialization. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort high); agentphase2-reviewer
|
Bots are done — your move: post |
…is proven The getIdentityByNonUniquePublicKeyHash transport entry declared no needs_protocol_version. NonUniquePublicKeyHashQuery picks V1 only once the network basis is 14, but the blanket `Query<T> for T` lets a caller pass a raw IdentityRequest carrying V1 to Identity::fetch, skipping that selector. On a network proven only at 13 the request went out, every node below 14 refused it with UNKNOWN, and the SDK retried and banned honest nodes. V1 now declares protocol 14 (V0 and an empty version declare nothing), so the fetch path refuses it with ProtocolVersionNotActive, or asks the network first, without contacting a node. The selector is unchanged: it picks V1 only at a basis the gate already lets through. The request inventory verdict for the V1 arm is now Gate(14). Answers thepastaclaw's blocking finding on #5608. Tests would have caught this in CI: ✖ before fix, ✔ after, with grpc.rs swapped back to origin/v5.0-dev and the new tests kept: - should_refuse_a_v1_non_unique_key_lookup_until_protocol_14_is_verified: ✖ "expected a refusal ..., got Err(DapiClientError(Transport(Grpc( Status { code: Unknown, message: "unsupported query version", ... }))))" (the V1 request reached the node) - should_send_a_v1_non_unique_key_lookup_once_protocol_14_is_verified: ✖ probes 0 != 1 (a fresh SDK sent the caller's V1 without asking) - request_inventory should_need_the_declared_protocol_version_for_each_addition and should_need_protocol_14_only_for_composite_chained_token_pool_and_non_unique_v1_requests: ✖ left: None, right: Some(14) All ✔ with the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
587ba08 to
606cfbe
Compare
|
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 runtime change correctly gates only V1 non-unique identity lookups at protocol 14 while preserving V0 behavior, and the relevant Rust workspace check passed. The protocol-gate book page still says that V1 is selected only by the SDK and that it does not need a transport declaration, so it should be updated to document the new raw-request gate.
🟡 1 suggestion(s)
1 finding(s) not shown inline (the lines are not part of this PR's diff)
🟡 Suggestion: Update protocol-gate documentation for non-unique-key V1 requests
book/src/sdk/protocol-version-gate.md:22-25
The implementation now declares getIdentityByNonUniquePublicKeyHash V1 as requiring protocol 14, so hand-built V1 requests participate in the generic SDK gate and are refused or probed before reaching pre-14 nodes. This section still says that V1 is only selected by the SDK and groups it with additions that do not need a declaration, which no longer describes the complete behavior and could mislead callers about the safety of raw V1 requests. Add the request to the protocol-14 table and clarify that both the selector and the transport gate prevent V1 from reaching pre-14 nodes.
source: gpt-6.1-sol (phase2-reviewer: general, architecture-layering, platform-versioning, rust-quality)
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (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: platform-versioning); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 9: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 10: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
normalbygpt-6.1-sol(effort low) — This is a contained SDK/DAPI request-gating behavior change with meaningful protocol-version compatibility implications, but it does not itself alter consensus, cryptography, funds movement, or peer-facing deserialization. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - 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 high); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— general (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort high); 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 `book/src/sdk/protocol-version-gate.md`:
- [SUGGESTION] book/src/sdk/protocol-version-gate.md:22-25: Update protocol-gate documentation for non-unique-key V1 requests
The implementation now declares `getIdentityByNonUniquePublicKeyHash` V1 as requiring protocol 14, so hand-built V1 requests participate in the generic SDK gate and are refused or probed before reaching pre-14 nodes. This section still says that V1 is only selected by the SDK and groups it with additions that do not need a declaration, which no longer describes the complete behavior and could mislead callers about the safety of raw V1 requests. Add the request to the protocol-14 table and clarify that both the selector and the transport gate prevent V1 from reaching pre-14 nodes.
|
Bots are done — your move: post |
…ing protocol 14 The protocol-gate page grouped getIdentityByNonUniquePublicKeyHash V1 with additions that ban no node, on the grounds that only the SDK's selector sends it. A hand-built V1 request did reach nodes before 14, which refuse it with UNKNOWN and got banned for it; the transport entry now declares protocol 14 for V1. The page lists it in the protocol 14 table and keeps only the INVALID_ARGUMENT additions in the 'bans no node' paragraph. Answers thepastaclaw's suggestion on #5615. Docs only, no behaviour change, so no test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
📖 Book Preview built successfully. Download the preview from the workflow artifacts. Updated at 2026-10-28T14:52:46.869Z |
|
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 change correctly gates hand-built V1 non-unique-key identity requests at protocol 14 while preserving unrestricted V0 behavior. The transport metadata is propagated through the existing SDK fetch and delegated request paths, and the inventory, integration tests, and documentation are consistent with the fix. Relevant CI checks passed; the remaining queued Kotlin SDK check is unrelated to this Rust/DAPI change.
🔴 0 blocking | 🟡 0 suggestion(s) | 💬 0 nitpick(s)
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (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: platform-versioning); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 8: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 9: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 10: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
normalbygpt-6.1-sol(effort low) — This is a contained but cross-crate Rust logic change to protocol-version gating and request dispatch, without modifying consensus, cryptography, funds movement, storage, or peer-facing deserialization. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity quota lookup failed),glm-5.3-flash(not used above high effort; tier asks max) - 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 high); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— general (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort high); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify the current code and confirm that no unresolved issues remain.
No unresolved findings remain from the prior review on this head.
|
Bots are done — your move: post |
Issue being fixed or feature implemented
This fixes thepastaclaw's blocking finding on #5608 (reply).
In
rs-dapi-client, thegetIdentityByNonUniquePublicKeyHashtransport entry declared noneeds_protocol_version.NonUniquePublicKeyHashQuerysends V1 only once the network basis (the lower of the stored version and the verified network version) is 14. Butrs-sdkhas a blanketimpl<T> Query<T> for T, so a caller can pass a rawIdentityRequest::GetIdentityByNonUniquePublicKeyHashcarrying V1 straight toIdentity::fetchand skip that selector.On a network proven only at protocol 13, that request still went out. A node below 14 refuses V1 with gRPC
UNKNOWN: a 4.x node fails to decode the version, and a 5.0 node running protocol 13 rejects it as an unsupported query version. The SDK treats that status as a node fault, so it retried the request and banned honest nodes.The bug shipped in 5.0.1. This PR targets
v5.0-devfor the 5.0.x line, and the nextv5.0-dev→v5.1-devforward merge carries it into v5.1. It was first opened againstv5.1-devwith no v5.0 backport planned; that no longer applies.What was done?
packages/rs-dapi-client/src/transport/grpc.rs: the entry now declaresneeds_protocol_version, the same way the neighbouring entries that match onrequest.versiondo. V1 needsPROTOCOL_VERSION_OF_5_0(14). V0 andNoneneed nothing.Error::ProtocolVersionNotActive, or asks the network for its version first, before contacting any node.packages/rs-dapi-client/tests/request_inventory.rs:GetIdentityByNonUniquePublicKeyHashRequest.v1changes fromNoGate(...)toGate(14).None/ V1 →Some(14)pair, and is renamed to match.packages/rs-sdk/src/sdk/protocol_gate_tests.rs: new tests that replay the signed identity-discovery vectors through the gate harness. These vectors are signed with the same test quorum key as the protocol-gate vectors.should_refuse_a_v1_non_unique_key_lookup_until_protocol_14_is_verified: the SDK is verified at 13 and the node would answer V1 withUNKNOWN. A raw V1 passed toIdentity::fetchis refused withProtocolVersionNotActiveafter one probe; it is never sent and no node is banned. A raw V0 still goes out and finds the identity.should_send_a_v1_non_unique_key_lookup_once_protocol_14_is_verified:packages/rs-sdk/src/sdk/identity_discovery_tests.rs:hash,requestandresponseare nowpub(super)so the gate tests can reuse them.CheckedAtis shared between test modules the same way.book/src/sdk/protocol-version-gate.md: the protocol 14 table now listsgetIdentityByNonUniquePublicKeyHashrequest version 1. The page no longer groups it with the additions that ban no node.How Has This Been Tested?
Red → green. On the
v5.0-devbase, I swappedgrpc.rsback toorigin/v5.0-devand kept the new tests. Every new or changed assertion fails, and all of them pass with the fix:should_refuse_a_v1_non_unique_key_lookup_until_protocol_14_is_verifiedexpected a refusal of get_identity_by_non_unique_public_key_hash, got Err(DapiClientError(Transport(Grpc(Status { code: Unknown, message: "unsupported query version", .. })))): the V1 request reached the nodeshould_send_a_v1_non_unique_key_lookup_once_protocol_14_is_verifiedprobes 0 != 1: a fresh SDK sent the caller's V1 without asking the networkrequest_inventory::should_need_the_declared_protocol_version_for_each_additionleft: None, right: Some(14)request_inventory::should_need_protocol_14_only_for_composite_chained_token_pool_and_non_unique_v1_requestsleft: None, right: Some(14)Local runs on the final tree:
cargo test -p dash-sdk -p rs-dapi-client --all-features --locked --lib --bins --tests --no-fail-fast: 814 passed, 0 failed. The 27 ignored are the existing live-network tests and the inventory export.cargo clippy -p rs-dapi-client -p dash-sdk --all-targets --all-features --locked -- --no-deps -D warnings: clean.cargo fmt --all -- --check: clean.Breaking Changes
None for callers of
NonUniquePublicKeyHashQuery. Only a hand-built V1 request sent through the fetch path changes behaviour: before protocol 14 is proven, it is now refused locally instead of getting nodes banned.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 ·
f585aa6/self-reviewedWhen 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