Skip to content

Commit 85f1707

Browse files
lklimekcodex
andcommitted
fix(sdk): preserve legacy proof compatibility on v5.0
Restore the legacy nested nonunique identity proof response while preserving current server output and all verifier security, signature and freshness gates. Backport only the identity-discovery feature commits onto v5.0-dev, adapting fixture signing to its existing BLS API and regenerating latest fixtures at PV14. Separate signed producer query layout from retained verifier rules for state transition outcomes. A genuine PV13 document outcome verifies under a retained PV14 verifier without an invented owner balance; PV14 still requires its balance. Keep existing Drive callers and all shipped protocol generations unchanged. Validate current Drive ABCI response codecs, signed proof adversarial cases, SDK version policy, read-only mainnet/testnet discovery and pinned client output. Scoped CI clippy, verify-only Drive clippy, rustfmt and wire tests pass. Original commits: bb5b1ec, 6f40494. <sub>🤖 Co-authored by [Claudius the Magnificent](https://github.com/lklimek/claudius) AI Agent</sub> Co-Authored-By: Codex GPT-6 <noreply@openai.com>
1 parent 79693ec commit 85f1707

52 files changed

Lines changed: 3530 additions & 640 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎book/src/sdk/identity-keys.md‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ let identity_ids = drive.fetch_identity_ids_by_non_unique_public_key_hash(
444444

445445
`getIdentityByNonUniquePublicKeyHash` returns the first matching identity in
446446
lexicographic identity-ID byte order. `start_after` is exclusive; use the returned
447-
ID to fetch the next match. A proved response contains one standard `Proof`
447+
ID to fetch the next match. Current nodes return one standard `Proof`
448448
(result field 4). It proves the complete index prefix through that identity and
449449
all its keys, balance and revision at the same signed root. An absent hash or
450450
exhausted cursor proves the entire remaining range is empty. A missing identity
@@ -457,12 +457,17 @@ versions require an SDK update and fail closed. The Rust SDK still returns
457457
shape. The direct WASM verifier takes one proof blob and returns a root that the
458458
caller must authenticate independently.
459459

460-
The nested double-proof response (retired field 2) has been removed with no
461-
fallback. Stable v4.1.1 clients and nodes use that old format and are incompatible
462-
with this proved endpoint during a mixed rollout. Update clients and nodes
463-
together; mismatched or unsupported-future-version responses can trigger the
464-
existing SDK retry and node-ban behavior. Unproved response field 1 and the
465-
request fields remain unchanged.
460+
The SDK also accepts the legacy nested response at field 2. It strictly verifies
461+
its first-after index proof and complete identity proof, requires equal roots,
462+
and authenticates that root with the trusted quorum key and signed metadata.
463+
Only proved index absence permits an omitted identity proof. Both formats require
464+
GroveDB V1 or newer; failed current-format proofs are never retried as legacy.
465+
The response field selects the format, independently of protocol version: current
466+
proofs can also be produced at protocol 13. Freshness checks and authenticated
467+
version learning apply after successful verification. Existing nodes continue
468+
emitting field 4; unproved response field 1 and request fields are unchanged.
469+
For a legacy response, `fetch_with_metadata_and_proof` returns the signed index
470+
`Proof`; independent replay of the full verification needs both original blobs.
466471

467472
**Fetch all keys for an identity:**
468473
```rust

‎book/src/sdk/put-operations.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,13 @@ for a proof made at an earlier version or a transition without an owner);
243243
`put_to_platform_and_wait_for_response_with_owner_balance` return it next to
244244
the document. The balance is a snapshot at the proof's block: it may already
245245
include later transitions of the same identity.
246+
247+
The signed producer version selects the execution-proof query layout. A client
248+
retaining protocol 14 verifier rules can therefore authenticate a protocol 13
249+
outcome without inventing a balance. A protocol 14 outcome must still prove the
250+
balance; verification never retries a malformed current proof as an older layout.
251+
Signature and freshness checks run before the SDK learns the producer version.
252+
246253
`put_to_platform_and_wait_for_response_with_owner_balance_and_metadata` also
247254
returns the verified response metadata, whose `height` is that block, so a
248255
wallet keeping the balance can order it against balances it read elsewhere; it

‎packages/dapi-grpc/clients/drive/v0/nodejs/drive_pbjs.js‎

Lines changed: 260 additions & 2 deletions
Large diffs are not rendered by default.

‎packages/dapi-grpc/clients/platform/v0/nodejs/platform_pbjs.js‎

Lines changed: 260 additions & 2 deletions
Large diffs are not rendered by default.

‎packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js‎

Lines changed: 298 additions & 1 deletion
Large diffs are not rendered by default.

‎packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.h‎

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.m‎

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/dapi-grpc/clients/platform/v0/python/platform_pb2.py‎

Lines changed: 649 additions & 582 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6972,6 +6972,11 @@ export namespace GetIdentityByNonUniquePublicKeyHashResponse {
69726972
getIdentity(): GetIdentityByNonUniquePublicKeyHashResponse.GetIdentityByNonUniquePublicKeyHashResponseV0.IdentityResponse | undefined;
69736973
setIdentity(value?: GetIdentityByNonUniquePublicKeyHashResponse.GetIdentityByNonUniquePublicKeyHashResponseV0.IdentityResponse): void;
69746974

6975+
hasLegacyProof(): boolean;
6976+
clearLegacyProof(): void;
6977+
getLegacyProof(): GetIdentityByNonUniquePublicKeyHashResponse.GetIdentityByNonUniquePublicKeyHashResponseV0.IdentityProvedResponse | undefined;
6978+
setLegacyProof(value?: GetIdentityByNonUniquePublicKeyHashResponse.GetIdentityByNonUniquePublicKeyHashResponseV0.IdentityProvedResponse): void;
6979+
69756980
hasProof(): boolean;
69766981
clearProof(): void;
69776982
getProof(): Proof | undefined;
@@ -6996,6 +7001,7 @@ export namespace GetIdentityByNonUniquePublicKeyHashResponse {
69967001
export namespace GetIdentityByNonUniquePublicKeyHashResponseV0 {
69977002
export type AsObject = {
69987003
identity?: GetIdentityByNonUniquePublicKeyHashResponse.GetIdentityByNonUniquePublicKeyHashResponseV0.IdentityResponse.AsObject,
7004+
legacyProof?: GetIdentityByNonUniquePublicKeyHashResponse.GetIdentityByNonUniquePublicKeyHashResponseV0.IdentityProvedResponse.AsObject,
69997005
proof?: Proof.AsObject,
70007006
metadata?: ResponseMetadata.AsObject,
70017007
}
@@ -7024,9 +7030,40 @@ export namespace GetIdentityByNonUniquePublicKeyHashResponse {
70247030
}
70257031
}
70267032

7033+
export class IdentityProvedResponse extends jspb.Message {
7034+
hasGrovedbIdentityPublicKeyHashProof(): boolean;
7035+
clearGrovedbIdentityPublicKeyHashProof(): void;
7036+
getGrovedbIdentityPublicKeyHashProof(): Proof | undefined;
7037+
setGrovedbIdentityPublicKeyHashProof(value?: Proof): void;
7038+
7039+
hasIdentityProofBytes(): boolean;
7040+
clearIdentityProofBytes(): void;
7041+
getIdentityProofBytes(): Uint8Array | string;
7042+
getIdentityProofBytes_asU8(): Uint8Array;
7043+
getIdentityProofBytes_asB64(): string;
7044+
setIdentityProofBytes(value: Uint8Array | string): void;
7045+
7046+
serializeBinary(): Uint8Array;
7047+
toObject(includeInstance?: boolean): IdentityProvedResponse.AsObject;
7048+
static toObject(includeInstance: boolean, msg: IdentityProvedResponse): IdentityProvedResponse.AsObject;
7049+
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
7050+
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
7051+
static serializeBinaryToWriter(message: IdentityProvedResponse, writer: jspb.BinaryWriter): void;
7052+
static deserializeBinary(bytes: Uint8Array): IdentityProvedResponse;
7053+
static deserializeBinaryFromReader(message: IdentityProvedResponse, reader: jspb.BinaryReader): IdentityProvedResponse;
7054+
}
7055+
7056+
export namespace IdentityProvedResponse {
7057+
export type AsObject = {
7058+
grovedbIdentityPublicKeyHashProof?: Proof.AsObject,
7059+
identityProofBytes: Uint8Array | string,
7060+
}
7061+
}
7062+
70277063
export enum ResultCase {
70287064
RESULT_NOT_SET = 0,
70297065
IDENTITY = 1,
7066+
LEGACY_PROOF = 2,
70307067
PROOF = 4,
70317068
}
70327069
}

0 commit comments

Comments
 (0)