feat: Directory Client: Attested Anchor#6948
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
|
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 ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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 |
f07b05f to
b5c054b
Compare
82aa39f to
8710237
Compare
b5c054b to
bc25634
Compare
8710237 to
bf6c620
Compare
Why
The trust model has a gap: the checkpoint / root-key layer (
LightClientAnchor's prerequisite) is blocked on a root key that doesn't exist yet. A second, independent authority is available today - the curated Tier-1 nym-api identity keys - so a quorum of them signing a snapshot gives a deployable trust root now, strictly stronger than trusting a single RPC and strictly weaker than the light client.What Changed
New anchor (
common/nym-directory-client/src/anchor/attested.rs)AttestedTrustAnchor<S>: constructed with trusted signer keys, a quorum thresholdK, chain-id, and contract address, or viawith_default_anchor(...)using a compiled-in default.DigestSnapshot/SignedDigestSnapshot: the attestation carries{height, app_hash, accumulator, node_identities_hash}- the directory digest AND a hash over the currentNodeId -> ed25519 identitymapping, both signed together so a quorum-verified snapshot proves authorship bindings too, with no chain query needed.AttestationSourcetrait (identity(),latest_snapshot(),snapshot_at(height)) - transport-agnostic; concrete HTTP transport is a follow-up.refresh()seeds a height from one source'slatest_snapshot()(shuffled, untrusted hint), then confirms it against every other source'ssnapshot_at(H), avoiding cadence-boundary splits from comparing independently-reported "latest" heights.reach_quorumgroups candidates by exact attested value, counts distinct signers, accepts the first group to reachK.AttestedTrustAnchor::majority_quorum(n)derives the default quorum as a simple majority of however many signers are configured, rather than a separately hardcoded threshold - so growing the default signer set later doesn't need a second change to keep a quorum number in sync.Default anchor (
common/network-defaults/src/{mainnet,network}.rs)DIRECTORY_ATTESTATION_SOURCES: mainnet's known nym-api identity keys + URLs, following the same pattern as the existingUPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY. Only 2 of 3 Nym SA nym-apis are included - the third has no way to expose its identity key yet (see Follow-ups).default_directory_attestation_sources(): env-var overridable (DIRECTORY_ATTESTATION_SOURCESJSON), mirroringNYM_APIS/NYM_VPN_APIS; falls back to the compiled mainnet list otherwise. Wired intosetup_env()'s existing backfill so real binaries loading a static.envfile pick up the default with no extra config.Data-source-agnostic verification (
common/nym-directory-client/src/verify.rs,client.rs)verify_directory(...): extracted fromDirectoryClient::verified_directory's body - digest recompute, optional node-identities-hash recompute, per-entry authorship attribution - takes pre-fetched data, noCosmWasmClientinvolved at all.verify_directory_offline(...): same core, but requires a node-identities hash (NodeIdentitiesHashUnavailableif none given) instead of silently skipping authorship verification - the entry point for callers with no chain RPC connection at all.DirectoryClient::verified_directoryis now a thin wrapper: fetch viaself.clientas before, then callverify_directory(.., None)- unchanged behavior forProvenTrustAnchor/LightClientAnchor.Known gaps / explicitly deferred
AttestationSource: both explicitly out of scope, follow-up changes; this change fixes the wire format they must emit/consume.This change is