update sepolia lc + runbook#18
Conversation
Greptile SummaryThis PR recovers the Sepolia SP1 light client from an expired state and introduces the full tooling + runbook to make this operation repeatable. It combines a light client state refresh, a new
Confidence Score: 5/5Safe to merge — the changes are well-guarded operational tooling with a corresponding runbook, plus a genuine bug fix for vm.writeJson path syntax that was silently miswriting deployment JSON. The vm.writeJson bracket-path bug fix is correct and consistent across all three Solidity scripts. The new deploy-fresh-light-client-state recipe has prerequisite guards, interactive confirmation, set -euo pipefail, and the decode_create_client.py scanner uses a sound structural algorithm that fails loudly on ambiguous or missing candidates. CI changes are additive and conservative. No files require special attention. The deploy.just recipe and decode_create_client.py are the most novel pieces, and both are well-structured with clear error paths. Important Files Changed
Reviews (2): Last reviewed commit: "address review: decimal chain id example..." | Re-trigger Greptile |
- DeploySP1ICS07Tendermint.sol: read CLIENT_ID from env when set so the script can run non-interactively (vm.prompt fails without a TTY in CI) - verify job: run read-only VerifyDeployment.sol instead of the fresh-deployment-only Deploy*.sol scripts - verify job: source RPC URLs from MAINNET_RPC_URL / SEPOLIA_RPC_URL repository secrets (the rpc_url JSON key no longer exists) - verify all environments independently (fail-fast: false) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- deploy.just: DST_CHAIN examples now use decimal chain ids (11155111) matching the runbook, instead of hex (0x1) - deploy.just: add -r to read so backslashes in input aren't interpreted Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@greptile-ai re-review |
|
|
||
| This runbook explains how to recover an **expired `SP1ICS07Tendermint` light client** (an IBC light client on Ethereum that tracks a Cosmos chain). It is written for someone with no prior context: it covers what the problem is, the systems involved, the exact commands, and every gotcha we hit doing it for real. | ||
|
|
||
| For the *normal* (non-expired) light-client migration ceremony, see [`upgrade-light-client.md`](./upgrade-light-client.md). This runbook is the **expired** variant — it adds a step to regenerate fresh trusted state, then reuses the same deploy + migrate flow. |
There was a problem hiding this comment.
(Side note) So we use the same trusted state when the client is not expired. Interesting, maybe we should consider always using a new trusted state.
| # Step 1 proof-api module identifiers (see step 1 for how to find them): | ||
| SRC_CHAIN=<cosmos-chain-id> | ||
| DST_CHAIN=<eth-chain-id> # decimal chain id, e.g. 11155111 for Sepolia | ||
| PROOF_TYPE=groth16 # MUST match the existing client's zk algorithm | ||
|
|
||
| # Step 3 Safe (the Safe that holds PROPOSER on the timelock): | ||
| SAFE_ADDRESS=0x... |
There was a problem hiding this comment.
Maybe these should be added to .eureka-env.example, and you could perhaps just link to that?
| - **The proof-api (a.k.a. eureka-relayer)** — a gRPC service that builds unsigned IBC txs. Its `CreateClient` method queries the Cosmos RPC and returns the **creation calldata** for a fresh `SP1ICS07Tendermint` (no proof generated). We use it as the source of fresh trusted state. It runs in k8s (see step 1 for access). | ||
|
|
||
| ### ⚠️ Version drift — verify against the live chain, not local source | ||
| The version the contracts were **deployed** from can differ from what the repo currently **compiles** and from the **running** proof-api image. Concretely, on the testnet recovery the live `ICS26Router` used OZ `AccessControl` while the pinned `solidity-v2.0.0` source uses `AccessManaged`. **Always confirm access control / addresses against the live contract** (`cast call`), not the checked-out source. |
There was a problem hiding this comment.
This is not true. Testnet version should be v2.0.0. v3.0.0 uses access manager.
| The version the contracts were **deployed** from can differ from what the repo currently **compiles** and from the **running** proof-api image. Concretely, on the testnet recovery the live `ICS26Router` used OZ `AccessControl` while the pinned `solidity-v2.0.0` source uses `AccessManaged`. **Always confirm access control / addresses against the live contract** (`cast call`), not the checked-out source. | |
| The version the contracts were **deployed** from can differ from what the repo currently **compiles** and from the **running** proof-api image. Concretely, on the testnet recovery the live `ICS26Router` used OZ `AccessControl` while the pinned `solidity-v3.0.0` source uses `AccessManaged`. **Always confirm access control / addresses against the live contract** (`cast call`), not the checked-out source. |
| ## 4. Prerequisites | ||
|
|
||
| - Tooling: `foundry` (forge/cast/chisel), `bun`, `just`, `jq`, `fzf`, **`grpcurl`**, **`python3`**, `kubectl`. | ||
| - **Proof-api reachable** for step 1 (k8s port-forward — see step 1). |
There was a problem hiding this comment.
I recommend linking the markdown for step 1 here. I was confused since sections are numbered in this doc, but step numbers are introduced later. So I actually jumped to Section 1 (instead of Step 1)
| ``` | ||
| If instead an EOA holds the role, use the direct `just ops-migrate-light-client` and skip the Safe ceremony. | ||
|
|
||
| ### 8b. `SAFE_ADDRESS` must point at the real Safe |
There was a problem hiding this comment.
Yes! We do this to be able to use the same recipes and test the runbooks on testnet.
If you drop me an address, I’ll add you.
There was a problem hiding this comment.
This code is quite hard to read. I don't really get it. So I'll skip reviewing it. Maybe we can replace it in the longer term
| address roleManager, # arg 7 | ||
| ) | ||
|
|
||
| We do NOT know the creation-bytecode length and we must NOT assume it matches any locally compiled |
There was a problem hiding this comment.
It doesn't matter as long as the bytecode is verified on etherscan? But ok
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
closes: PLAT-1083