Skip to content

update sepolia lc + runbook#18

Open
gjermundgaraba wants to merge 10 commits into
mainfrom
gjermund/update-sepolia-lc
Open

update sepolia lc + runbook#18
gjermundgaraba wants to merge 10 commits into
mainfrom
gjermund/update-sepolia-lc

Conversation

@gjermundgaraba
Copy link
Copy Markdown
Contributor

@gjermundgaraba gjermundgaraba commented Jun 1, 2026

closes: PLAT-1083

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 1, 2026

Greptile Summary

This 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 deploy-fresh-light-client-state just recipe backed by a proof-api gRPC call, and a version-independent Python decoder for the returned calldata.

  • Expired light client recovery: deployments/testnet/11155111.json updated with new implementation address and refreshed trusted state (latest height 0x10bc226); new deploy-fresh-light-client-state recipe automates the proof-api → decode → JSON-write pipeline with guards and an interactive confirmation step.
  • vm.writeJson path bug fixed across AddLightClient.sol, DeploySP1ICS07Tendermint.sol, and UpdateLightClientState.sol — bracket syntax (.light_clients['0']) was silently creating junk top-level keys; corrected to dot notation (.light_clients.0).
  • CI hardened: CLIENT_ID: "" env var enables non-interactive DeploySP1ICS07Tendermint.sol runs in the local test job; fail-fast: false lets independent chain verifications complete even if one fails; RPC URLs now come from GitHub secrets instead of the deployment JSON.

Confidence Score: 5/5

Safe 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

Filename Overview
.github/workflows/deploy.yml CI improvements: CLIENT_ID env var for non-interactive deployments, fail-fast: false on matrix, and RPC URL now sourced from GitHub secrets via a chain-id case statement instead of the deployment JSON.
deploy.just Adds deploy-fresh-light-client-state recipe with full guard checks, service auto-discovery via gRPC reflection, and interactive confirmation before mutating the deployment JSON. Timelock info block also improved.
script/helpers/decode_create_client.py New version-independent ABI decoder that locates constructor args structurally without requiring local bytecode; raises on ambiguous or missing candidates.
script/DeploySP1ICS07Tendermint.sol Adds CLIENT_ID env-var bypass for non-interactive CI runs; fixes vm.writeJson paths from broken bracket syntax to dot notation.
script/AddLightClient.sol Bug fix: vm.writeJson path changed from .light_clients['N'] to .light_clients.N (correct dot-path traversal).
runbooks/recover-expired-light-client.md New comprehensive runbook covering the full expired-light-client recovery flow.

Reviews (2): Last reviewed commit: "address review: decimal chain id example..." | Re-trigger Greptile

Comment thread deploy.just Outdated
Comment thread deploy.just Outdated
gjermundgaraba and others added 2 commits June 1, 2026 13:21
- 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>
@gjermundgaraba
Copy link
Copy Markdown
Contributor Author

@greptile-ai re-review

Comment thread .github/workflows/deploy.yml

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.
Copy link
Copy Markdown
Member

@srdtrk srdtrk Jun 2, 2026

Choose a reason for hiding this comment

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

(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.

Comment on lines +71 to +77
# 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...
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not true. Testnet version should be v2.0.0. v3.0.0 uses access manager.

Suggested change
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).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Btw do we use safe in testnet?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Comment thread runbooks/recover-expired-light-client.md
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It doesn't matter as long as the bytecode is verified on etherscan? But ok

Comment thread script/DeploySP1ICS07Tendermint.sol
gjermundgaraba and others added 6 commits June 2, 2026 15:51
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>
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 2, 2026

PLAT-1083

@gjermundgaraba gjermundgaraba requested a review from srdtrk June 2, 2026 16:05
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.

2 participants