feat(cli,sdk): add l2 register-vk to register a prover verification key - #249
Merged
Conversation
… key Every ethrex upgrade of an L2 that verifies real proofs needs the new build's verification key registered against the commit hash it commits batches under. `commitBatch` rejects a commit hash it holds no key for, so an upgraded sequencer commits nothing at all until this is done — it looks like a stuck committer rather than a key problem. Doing it by hand is easy to get wrong in two ways, both of which this command removes: - The hashed value is the full git sha the binary reports, as ASCII. Hashing an abbreviated sha silently yields a different key. `--commit` takes the sha and hashes it, or accepts an already-hashed 32-byte value. - `upgradeSP1VerificationKey` is `onlyOwner`, and that owner is the Timelock in any deployment made since ethrex v9.0.0, so the call has to be routed through `emergencyExecute`. Passing `--timelock` does that; without it the direct call reverts with `OwnableUnauthorizedAccount`, which surfaces as an opaque abi-decode failure, so that revert is translated into a message saying to pass the flag. The key is read back after the transaction is mined, because a call routed to the wrong owner can be mined without taking effect. `--dry-run` prints the derived commit hash and the key currently on chain without sending, and a re-run when the key already matches is a no-op. Verified against a live v24 -> v25 upgrade: dry run reproduced the hand-computed commit hash, the registration went through the Timelock and read back correctly, a repeat run reported nothing to do, and omitting --timelock produced the translated error.
1 task
ilitteri
enabled auto-merge (squash)
August 26, 2026 17:21
ilitteri
disabled auto-merge
August 26, 2026 17:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Every ethrex upgrade of an L2 that verifies real proofs needs the new build's verification key registered against the commit hash it commits batches under. This has been true since ethrex v9.0.0, when verification keys became per-commit-hash and the Timelock became the OnChainProposer's owner.
It is not optional.
commitBatchrejects a commit hash the deployment holds no key for, so an upgraded sequencer commits nothing until the key is registered — every commit reverts withMissingVerificationKeyForCommit()(0xf6b9798e) while the L2 keeps producing blocks. The symptom looks like a stuck committer, not a missing key.Doing it by hand is easy to get wrong in two ways, and both failures look the same from the outside:
HEAD-inethrex --version. Hashing an abbreviated sha silently produces a different key, and the only symptom is that commits keep reverting. The ethrex docs carried a worked example using a shortened sha that does not reproduce; that is fixed in docs(l2): run the release upgrade test with a real prover, and fix the verification-key instructions ethrex#7203.upgradeSP1VerificationKeyisonlyOwner, and that owner is the Timelock, so the call has to be routed throughemergencyExecute(Security Council) or Governanceschedule+execute. Sending it straight to the OnChainProposer from an EOA reverts withOwnableUnauthorizedAccount(0x118cdaa7), which surfaces as an opaque abi-decode failure.Description
Adds
rex l2 register-vk(aliasvk) and the SDK functions behind it.--committakes the git sha and hashes it, or accepts an already-hashed 32-byte value, so the caller never has to know which form the contract wants.--timelockroutes throughemergencyExecute. Omit it only when an EOA still owns the contract. If the direct call is rejected as not-owner, the revert is translated into a message saying to pass the flag rather than an abi-decode error.--prover risc0targetsupgradeRISC0VerificationKey; the default is SP1.--dry-runprints the derived commit hash and the key currently on chain without sending.New:
sdk/src/l2/verification_key.rs(commit_hash_from_git_sha,get_verification_key,register_verification_key,Prover), plus the four contract signatures insdk/src/l2/constants.rs.How to test
Against a dev L2 deployed with
--sp1 true(this is the flow lambdaclass/ethrex#7203 documents as Step 3.6 of the release upgrade test):Verified end to end against a live v24.0.0 → v25.0.0 upgrade: the dry run reproduced a hand-computed commit hash, the registration went through the Timelock and read back correctly, a repeat run reported nothing to do, and omitting
--timelockproduced the translated error.cargo check --all-targets,clippyandfmtare clean.