Backport release/v6.6: Add frozen RPC router and Docker integration cluster (#3989) - #4024
Conversation
(cherry picked from commit 689f7d6)
PR SummaryMedium Risk Overview Build & localnet: New CI: Integration prepare job packages Reviewed by Cursor Bugbot for commit 3296241. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cd0b5d2. Configure here.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## release/v6.6 #4024 +/- ##
================================================
- Coverage 58.87% 57.99% -0.88%
================================================
Files 2228 2157 -71
Lines 183964 175837 -8127
================================================
- Hits 108302 101978 -6324
+ Misses 65894 64734 -1160
+ Partials 9768 9125 -643
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
…rgets The cherry-pick carried main's $(shell go env GOMODCACHE) into the two new frozen-rpc cluster targets. This branch hardcodes GO_PKG_PATH to $(HOME)/go/pkg and every other cluster target creates $(shell go env GOPATH)/pkg/mod. With a relocated GOMODCACHE the mkdir and the compose mount source diverge, so the bind mount lands on a root-owned empty directory and the node build hangs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Backport of #3989 to
release/v6.6.Describe your changes and provide context
Cherry-pick of 689f7d6, plus one branch adaptation. This adds:
frozen-rpc-router, an EVM JSON-RPC proxy that routes block-scoped requests to the matching frozen node and all other traffic to the live node.seid, and the topology in the integration-test CI matrix.All 8 new files are byte-identical to the merged commit on
main. The basedocker/docker-compose.ymlis byte-identical between the two branches, as are the 4 localnode scripts after this change.Commits
feat: add frozen RPC router cluster— the cherry-pick, with the conflict resolutions below.fix(build): use the branch GOPATH convention in frozen RPC cluster targets— see "Branch adaptation".Conflict resolution
Four conflicts came up. Every one is drift between
mainandrelease/v6.6, not part of the PR..github/workflows/integration-test-matrix.jsonmainextracted the matrix to JSON plus aset-matrixjob.release/v6.6keeps it inline in the workflow.Frozen RPC Routerrow inline, withcluster: "frozen-rpc-router", in the same positionmainuses. Nothing else in the JSON was needed, and nothing under.github/still references it..github/workflows/integration-test.yml(2 sites)mainhas.github/scripts/docker-registry-retry.shand anautobahn-integration-testsjob.release/v6.6has neither. The PR only reworded a comment at each site.release/v6.6text. Nothing to port.docker/localnode/scripts/step4_config_override.shmaindefaultsGIGA_EXECUTORandGIGA_OCCtotrue.release/v6.6defaults both tofalse.release/v6.6defaults. Ported only the PR change:VALIDATOR=${VALIDATOR:-true}and themode = "full"override. The overlay's explicitGIGA_*=falseexists becausemaindefaults totrue; on this branch it agrees with the default, so behaviour is unchanged for this topology and for every other cluster.docker/localnode/scripts/step5_start_sei.shmaincarriesSEID_PID=$!, which feeds a readiness loop thatrelease/v6.6does not have. The loop is context, not part of #3989.--freeze-height "${FREEZE_HEIGHT}". LeftSEID_PIDout, because this branch has no loop to consume it. See caveat 1.Branch adaptation
The cherry-pick carried
main's$(shell go env GOMODCACHE)into the two new frozen-rpc cluster targets. This branch hardcodesGO_PKG_PATH = $(HOME)/go/pkgatMakefile:23, and its other six cluster targets all create$(shell go env GOPATH)/pkg/mod. With a relocatedGOMODCACHEthemkdirand the compose mount source diverge, the bind mount lands on a root-owned empty directory, and the node build hangs with nobuild.complete. CI is unaffected, because the runner's default GOPATH makes the two paths coincide. Commit 2 aligns the new targets with this branch's convention.This does not address the pre-existing
GO_PKG_PATH/go env GOPATHdivergence on this branch, which affects all cluster targets identically and is out of scope here.Branch dependencies confirmed
--freeze-heightis registered onseid startatsei-cosmos/server/start.go:218. Freeze mode is already on this branch:5b9a56ba7"Disable mempool traffic in freeze mode (Backportrelease/v6.6: Disable mempool traffic in freeze mode #4006)".VALIDATORandFREEZE_HEIGHTto literal values, so it does not need the basedocker-compose.ymlto declare them.docker compose configconfirms node1 getsFREEZE_HEIGHT=10andVALIDATOR=false, node2 gets20andfalse, and node0 and node3 stay validators. Direct RPC ports 8547 / 8549 / 8545 match the test and the README. IP192.168.10.14is free.sei-tendermint/node/public.goon this branch hasvalidateFreezeMode, which rejectsfreezeHeight > 0in validator mode.mainremoved that check. So themode = "full"sed is load-bearing here, and a failed sed is a loud node-start failure rather than two frozen validators halting consensus at height 10. I verified the sed applies:docker/localnode/config/config.toml:18is exactlymode = "validator", one match, and the piped result ismode = "full".init.completeandpersistent_peers.txtwrites sit outside the newVALIDATORguard, andstep3_add_validator_to_genesis.shiteratesfor FILE in *rather than a fixed count. The router container overridesentrypoint, so it never runsdeploy.shand never adds a 5thlaunch.completeline — the ungated 4-line wait stays correct.ReadOnlyin freeze mode (from Backportrelease/v6.6: Disable mempool traffic in freeze mode #4006) gates only mempool and evidence paths viarequireWritable. Queries are untouched, so frozen nodes serveeth_blockNumberandeth_getBlockByNumbernormally.Caveats for the release owner
Neither is a backport defect. Both are consequences of this branch, and both are worth a decision before merge.
launch.completeis a weaker barrier here than upstream. Onmainit means the node's query surface answers; on this branch it meansseidwas backgrounded. Aseid startthat dies immediately still writes it. The frozen row is the only matrix row withVerify Sei Chain is runninggated off, so nothing between compose-up and the test checks node liveness. The test self-gates with a 3-minutewaitForHeadper endpoint, so this costs diagnosability, not correctness: a dead frozen node surfaces as a timeout withlast height 0instead of a pointed error. Backportingmain's step5 readiness loop is a reasonable follow-up.The router's block-parameter table does not cover this branch's legacy
sei_*/sei2_*surface.cmd/frozen-rpc-router/router.go:27lists onlyeth_*anddebug_*.mainnarrowedevmrpc/sei_legacy.goto 3 live methods (the address and Cosmos helpers); this branch still has 33, anddocker/localnode/config/app.toml:294enables the block-scoped ones on the localnet —sei_getBlockByNumber,sei_getBlockReceipts,sei_getLogsand more. A request forsei_getBlockByNumberat a pre-freeze height misses the table, falls through to the live node, and returns not-found with a header asserting the live route was deliberate. The integration test does not catch this, because the localnet's live node still holds block 9. Production exposure is limited: the default allowlist atevmrpc/config/config.go:531is only the three non-block-scoped helpers, so an operator must widenenabled_legacy_sei_apisto reach it. The router code is byte-identical tomain, so this is an upstream coverage gap that is simply wider on this branch.Testing performed to validate your change
go build ./cmd/frozen-rpc-routergo test -race ./cmd/frozen-rpc-routergo test -tags frozen_rpc_integration -run '^$' ./integration_test/frozen_rpc_router/...go vet ./cmd/frozen-rpc-router/...staticcheck ./cmd/frozen-rpc-router/...golangci-lint run --timeout 10m0s ./cmd/frozen-rpc-router/...at the CI pin v2.8.0gofmt -l cmd/frozen-rpc-router integration_test/frozen_rpc_routergit diff --checksh -non all 4 changed scriptsdocker compose configon the merged overlay.github/workflows/integration-test.ymlparsed as YAMLclusterconditionsmake -non both new cluster targetsgo test ./sei-tendermint/node/ -run FreezeFreeze mode enabled ... mode=full, confirming freeze boots as a full node on this branchdocker/localnode/config/config.tomlpiped through themode = "full"sedTwo notes on lint. golangci-lint 2.12.2 reports 5 findings on
cmd/frozen-rpc-router(1goconst, 4 gosecG704/G706taint rules). CI pins v2.8.0, which reports 0. The Go sources are byte-identical tomain, so those findings apply tomaintoo. They are a linter-version difference, not a backport regression. Separately,make fmtcheckdoes not exist on this branch, so I rangofmt -ldirectly.I did not run
make frozen-rpc-router-integration-testlocally. It needs a full 4-node Docker cluster build. What it would prove and no static check can: that the 2-validator genesis produces blocks past height 20, and that the frozen nodes stop at exactly 9 and 19. That is what the newIntegration Test (Frozen RPC Router)CI row is for. One data point in its favour: this branch'sconfig.tomlcarriesunsafe-commit-timeout-override = "50ms", whichmaindoes not, so the chain should reach height 20 faster here than upstream.Note for whoever merges:
Integration Test (Frozen RPC Router)is a new check name, so branch protection forrelease/v6.6may need updating.🤖 Generated with Claude Code