Skip to content

feat: deterministic RPC semantic identity - #415

Merged
SunSi12138 merged 402 commits into
devfrom
feature/issue-396-deterministic-rpc-identity
Sep 4, 2026
Merged

SunSi12138 merged 402 commits into
devfrom
feature/issue-396-deterministic-rpc-identity

Conversation

@SunSi12138

Copy link
Copy Markdown
Owner

Implements Phase 1 of #396.

Scope:

  • fixed-width deterministic RPC semantic hash primitives
  • per-final-codec CodecHash
  • method / contract / assembly semantic hashes derived from the finalized codec graph
  • local generated-registration consistency based on CodecHash
  • deterministic identity tests and cleanup of legacy schema/wire identity plumbing

Out of scope for this PR:

  • publishing/discovering the remote assembly hash on the transport
  • client/server bind-time equality validation
  • dynamic replacement/coexist/drain protocol work

The implementation builds on the final assembly-owned codec routing from #386. Dispatch route IDs remain separate from semantic compatibility hashes.

Closes neither #396 nor its Phase 2 work until remote bind validation is implemented.

Copy link
Copy Markdown
Owner Author

Handoff — #396 Phase 1

Current branch/head:

  • feature/issue-396-deterministic-rpc-identity
  • 34a9befb23ec066de1c2bbed38b25e5040fd966d
  • PR remains Draft. Do not merge yet.

All changes from this work session are committed on the branch; there is no remaining uncommitted connector-side workspace.

Architectural state

Phase 1 is intentionally scoped to local deterministic identity only. Remote publication/discovery and bind-time equality remain Phase 2.

Implemented so far:

  • Added fixed-width RpcHash128.
  • Added per-final-codec CodecHash plumbing.
  • CodecHash is graph-specific, not implementation-class-specific: the same generated factory implementation may be reused by global/default and contract-owned graphs while carrying different final hashes.
  • Generated manifest now exposes RpcAssemblyHash.
  • Added semantic composition path:
    • final payload CodecHash
    • MethodHash
    • ContractHash
    • RpcAssemblyHash
  • DTO hash input uses RPC-visible wire semantics plus child codec hashes.
  • Collection hash input uses collection kind plus child codec hashes.
  • Framework primitives use fixed semantic tokens.
  • Enum identity derives from underlying codec semantics.
  • UnsafeBlit identity uses physical layout inputs and deliberately excludes field names, MVID/build identity, unrelated assembly identity, etc.
  • Generated assemblies publish default/global per-type codec hashes through SharpLinkGeneratedCodecIdentityAttribute; downstream generation can consume the referenced assembly's fixed hash rather than hashing the CLR type name.
  • Added RpcCodecSemanticIdentity fixed-width opaque semantic identity for handwritten/custom/adapter boundaries.
  • Removed the old RpcCodecImplementationAttribute custom-codec identity entry point.
  • Removed adapter wire-identity registration plumbing that was only serving the legacy identity model.
  • Runtime generated-registration conflict detection now prefers exact CodecHash equality.
  • Deterministic identity tests have started landing, including opaque semantic identity coverage and removal of legacy identity usage in those tests.

Important remaining cleanup

The migration is not finished. In particular:

  1. IRpcGeneratedCodecFactory still exposes legacy SchemaId + WireFormatId alongside CodecHash. These must be removed once all generated/runtime/test callers are migrated.
  2. Runtime currently retains a temporary zero-hash legacy fallback for old/manual factories. Remove that fallback together with the legacy factory identity properties; final local registration consistency should be exact CodecHash only.
  3. Finish removing legacy SchemaId/WireFormatId validation/manifest/test fixtures and any old compile-time descriptor semantics that still treat them as compatibility identity.
  4. Finish referenced-generated-codec handling so current generated dependencies always resolve published fixed hashes; any temporary legacy fallback must not become part of the final model.
  5. Complete determinism/semantic-change coverage required by Design deterministic RPC wire identity and assembly-level contract validation #396:
    • same semantics across rebuild/platform => same hash
    • unrelated implementation change => same hash
    • DTO wire-semantic change => different hash
    • final route/custom semantic identity change => different hash
    • UnsafeBlit physical layout change => different hash
    • UnsafeBlit field rename with same layout => same hash
    • shared payload across manifests => same CodecHash
    • RPC method/contract semantic change => different RpcAssemblyHash
  6. Keep dispatch IDs/fingerprints separate from semantic compatibility hashes; do not repurpose old route IDs as MethodHash/ContractHash.
  7. Do not implement transport publication / remote RpcAssemblyHash equality in this Phase 1 PR unless deliberately expanding the scope. That remains Phase 2 of Design deterministic RPC wire identity and assembly-level contract validation #396.

CI handoff

Latest exact head checked: 34a9befb....

Current exact-head CI is not green yet:

  • PR Quick #2549: failed. One confirmed failure is the windows-11-arm codec producer failing during Setup .NET before repository code executes; inspect the remaining jobs before classifying the whole run.
  • Codec Padding Security Evidence feat(server): capture admission program generation per request #323: failed and still needs log inspection.
  • Earlier heads had Formatting + Debug/Release builds passing and the cross-platform codec compatibility matrix passing; do not use those older runs as final evidence for 34a9befb.

A prior directly-related Unit test (ConflictingManifestCodecsShouldRollbackBothAdapterScopes) was still asserting the old schema/wire error text after runtime conflict reporting switched to generic codec identity; update that test as part of legacy identity cleanup rather than restoring old wording.

Resume point

Recommended next sequence:

  1. Inspect exact-head #2549 + Padding feat(server): capture admission program generation per request #323 failures.
  2. Remove remaining IRpcGeneratedCodecFactory.SchemaId/WireFormatId surface and runtime zero-hash fallback.
  3. Clean validator/fixtures/compile-time descriptor references to legacy identity.
  4. Finish deterministic identity regression suite.
  5. Run exact-head PR Quick + CodeQL + Padding + Mobile to green.

No merge performed.

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found two semantic-identity gaps that can admit false compatibility; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.RpcIdentity.cs
Comment thread src/SharpLink.Generator/RpcGenerator.CodecIdentity.cs Outdated

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one more UnsafeBlit identity gap that can still admit false compatibility on 64-bit peers; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.CodecIdentity.cs Outdated

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a runtime path that bypasses the new 64-bit-only UnsafeBlit enforcement; details inline.

Comment thread src/SharpLink.Runtime/Codec/RpcCodecProvider.cs

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a contract-baseline gap for Contract-owned opaque codecs; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.ContractManifest.cs

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one remaining gap in the runtime-sized UnsafeBlit rejection; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.CodecPolicyOwnership.cs Outdated

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one remaining cross-platform identity assumption; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.CodecIdentity.cs Outdated

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a closed-codec identity gap for serializer adapters; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.CodecIdentity.cs Outdated

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found another platform-dependent UnsafeBlit layout dimension; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.CodecIdentity.cs Outdated

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a framework-string semantic-token mismatch; details inline.

Comment thread src/SharpLink.Generator/RpcGenerator.CodecIdentity.cs Outdated
@SunSi12138
SunSi12138 marked this pull request as draft September 4, 2026 10:38
@SunSi12138
SunSi12138 marked this pull request as ready for review September 4, 2026 10:38
@SunSi12138
SunSi12138 marked this pull request as draft September 4, 2026 10:45
@SunSi12138
SunSi12138 marked this pull request as ready for review September 4, 2026 10:45
@SunSi12138
SunSi12138 merged commit d980459 into dev Sep 4, 2026
36 checks passed
@SunSi12138
SunSi12138 deleted the feature/issue-396-deterministic-rpc-identity branch September 4, 2026 12:13
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.

1 participant