Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
bf9a2f0 to
24dd943
Compare
…lows that submit personhood proofs can be tested end to end
24dd943 to
efcfcd1
Compare
mordamax
left a comment
There was a problem hiding this comment.
The derivation is right. I reimplemented it independently against @noble/hashes and got c47086f94a7f4c05b7afd9f2339d3fea168f3823b5424ba1f7b31043d8ef60af for index 0 and 8d7f5e1510a7e8d813887e100f5a260ec9de60e68695477b93360ee7e3d16a9f for index 1, both matching the Rust vectors. Nothing in this repo pinned that agreement before, so ring-vrf-keys.ts is worth having either way.
The included slice and the getAlias mismatch are the two I'd want fixed before merge. The rest is smaller, take or leave:
ringLocationis dropped, so a people-lite request silently gets a people-full proof andRingNotFoundis unreachable- errors all become
Unknownwhen the 0.9.1 response type hasNotMemberandRingNotFound productIdisn't normalized before hashing (hosts do trim + NFC + lowercase)- the reads aren't pinned to one block and span two clients, so the ring can shift underneath
- two fresh WS clients plus metadata per proof is slow; could keep them for the server's lifetime
verifiablejscould be pinned (one_shotchanged arity and the proof encoding lost its compact prefix inside 1.x) and made optional, given it's a 7.5 MB wasm as a hard dep- the mnemonic goes over HTTP on every call and the first 12 chars land in the error string; Playwright captures request bodies into
trace.zipwhen tracing is on
Also, the description mentions a MNEMONIC-gated live test against previewnet but I don't see it in the diff, just the derivation vector. Did it get dropped?
| } | ||
| const latest = ringRoots[ringRoots.length - 1]; | ||
|
|
||
| const members = encodeMemberKeys( |
There was a problem hiding this comment.
Two things here.
The member list isn't sliced to RingKeysStatus.included. host-rust-core reads the status, checks status.included > ring_position before picking a candidate, and truncates:
The reason is spelled out at the top of the statement-allowance path — "the proof is built against the same members the runtime verifies against: the baked-in included prefix of the current ring":
Any ring with keys appended but not yet included, which is most of the time on a live chain, gives a member set that doesn't hash to the stored root, so validate_with_commitment throws.
Second, line 118: the exponent comes from the PeopleRingExponent constant, but on chain it's per collection — Members.Collections[collection].ring_size, or MembersSubscriber.RingCollectionExponents on the subscriber side. People and people-lite have their own sizes.
| container.handleAccountCreateProof((params, { ok }) => { | ||
| const [[productId, suffix], _ringLocation, message] = params; | ||
|
|
||
| if (config.ringVrfProofs) { |
There was a problem hiding this comment.
handleAccountGetAlias just above still returns the placeholder blake2(publicKey ++ "context") / blake2(publicKey ++ "alias"), so with ringVrfProofs on the two calls give different answers for the same account — different context and different alias.
Real hosts share context_bytes and the same entropy between account_alias and create_proof, so they agree by construction:
verifiablejs exports alias_in_context(entropy, context), so getAlias could go through the same server path.
| * Entropy behind the bandersnatch member key the People chain knows a full | ||
| * person by, at `//peopl.{tld}//index_bytes(0)`. | ||
| */ | ||
| export function fullPersonRingVrfEntropy( |
There was a problem hiding this comment.
I think tld is in the wrong slot. The per-network suffix is real — .test on previewnet, .paseo on pnv2 — but it appears in the allowance context, not the key domain:
The key domain is peopl.dot on every network:
With tld: 'test' you get 02114f37bddc9d5cb0f7bb978710e0e22eba94362cbe3a0a0b9ce991a858f052 instead of c47086f9…, so the README example on line 296 derives someone who doesn't exist.
|
|
||
| ### Added | ||
|
|
||
| - **Real ring-VRF proofs via the `ringVrfProofs` option.** `createRingVRFProof` used to answer with a deterministic stand-in, an sr25519 signature over the message, which no verifier accepts. Product flows that submit a proof, such as registry publishing or alias binding, could only ever be tested up to their failure path. With `ringVrfProofs` configured, the test-host server builds a genuine bandersnatch ring-VRF proof instead. It derives the RFC-0022 personhood member entropy from the account mnemonic at `//peopl.{tld}//index_bytes(0)` off the keyed ring-vrf tree, reads the ring the member sits in from the configured People chain, fetches the ring root from the subscriber chain, proves with `verifiablejs`, and validates against the live ring root before answering. When personhood is minted for that member on the target network, the proof passes network verification. |
There was a problem hiding this comment.
This doesn't say you need an account that's already a full person on the target network. It's in there as "when personhood is minted for that member", which reads like a bonus rather than the entry condition.
Can we say it plainly — the option is optional, but once you turn it on the identity isn't, and without one every call fails? Plus a pointer to how you get one. Right now someone with a fresh mnemonic has nowhere to go, and the README example (uri: process.env.MNEMONIC) suggests any mnemonic works.
Worth stating the failure mode too: CreateProofErr.Unknown with "Member key … is not in a ring".
Summary
createRingVRFProofcan now answer with genuine bandersnatch ring-VRF proofs instead of the sr25519 stand-in, so product flows that submit personhood proofs (registry publishing, alias binding) can be tested end to end.ringVrfProofsoption makes the server derive the account's RFC-0022 member entropy from its mnemonic, read the ring from the configured People chain, prove with verifiablejs, and validate against the live ring root before answering.src/ring-vrf-keys.tsand pinned to host-rust-core's iOS vectors; aMNEMONIC-gated live test builds chain-valid proofs against previewnet in both context forms.