Conversation
…s, evmigration store key added to upgrade, Cosmos EVM upgrade to 0.6.0
Reviewed 109ca1c (removed redundant Issues
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d4527beaf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Adds first-class Cosmos EVM integration support across Lumera’s node runtime, CLI, devnet tooling, upgrade handlers, JSON-RPC/OpenRPC, and CI pipelines.
Changes:
- Introduces EVM chain configuration/constants (chain ID, fee market defaults, denom metadata) and wires EVM modules into app/CLI/startup paths.
- Expands devnet + Hermes automation (upgrade flow, version/key-style detection, JSON-RPC ports, log archiving, test binary distribution).
- Adds extensive EVM-focused unit/integration tests and updates build/test/lint/release automation (OpenRPC generation, golangci-lint v2 config, workflows).
Reviewed changes
Copilot reviewed 141 out of 516 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| devnet/tests/evmigration/README.md | Adds devnet evmigration test tool README |
| devnet/scripts/wait-for-height.sh | Improves height wait UX + upgrade-halt detection |
| devnet/scripts/upgrade.sh | Adds idempotent upgrade flow + version checks |
| devnet/scripts/upgrade-binaries.sh | Verifies binary version + improves compose restart robustness |
| devnet/scripts/start.sh | Archives logs + optional claims CSV start flags |
| devnet/scripts/restart.sh | Archives logs + optional claims CSV start flags |
| devnet/scripts/configure.sh | Improves host-side shared volume/binary setup |
| devnet/main.go | Import ordering tweak |
| devnet/hermes/scripts/hermes-start.sh | Auto-detects key style based on chain version |
| devnet/hermes/scripts/hermes-configure.sh | Hermes address_type derivation based on key style |
| devnet/hermes/scripts/hermes-channel.sh | Uses eth HD path for EVM-era keys |
| devnet/hermes/config.toml | Devnet Hermes tuning (misbehaviour, clear interval) |
| devnet/hermes/Dockerfile | Updates Go base image + IBC-Go version arg |
| devnet/generators/docker-compose.go | Adds chain version detection + JSON-RPC port bindings |
| devnet/generators/config.go | Adds JSON-RPC default ports constants |
| devnet/dockerfile | Sets bash shell + installs ripgrep |
| devnet/default-config/devnet-genesis.json | Adds audit/evmigration genesis params + updates claim end time/amount |
| devnet/config/validators.json | Restructures supernode config + adds per-validator JSON-RPC ports |
| devnet/config/config.json | Adds evm_from_version, JSON-RPC config, and mnemonic lists |
| devnet/config/config.go | Extends devnet config schema (version, JSON-RPC, mnemonics) |
| devnet/.gitignore | Ignores generated compose/bin/logs |
| config/evm.go | Adds EVM chain constants (IDs, fees, gas) |
| config/config.go | Updates chain denom metadata + delegates Bech32/BIP44 setup |
| config/codec.go | Registers SDK + EVM crypto interfaces |
| config/bip44.go | Sets coin type to EVM (60) |
| config/bech32.go | Centralizes Bech32 prefix constants/helpers |
| config/bank_metadata.go | Provides/upserts canonical bank metadata for ulume/lume/alume |
| cmd/lumera/main.go | Treats context cancellation as graceful shutdown |
| cmd/lumera/cmd/root_test.go | Adds CLI wiring tests for EVM flags + key type defaults |
| cmd/lumera/cmd/root.go | Adds EVM modules to CLI basics + keyring options + config migration hook |
| cmd/lumera/cmd/jsonrpc_policy_test.go | Adds mainnet JSON-RPC namespace policy tests |
| cmd/lumera/cmd/jsonrpc_policy.go | Enforces disallowed JSON-RPC namespaces on mainnet |
| cmd/lumera/cmd/config_test.go | Verifies app config EVM/JSON-RPC defaults |
| cmd/lumera/cmd/config.go | Extends app.toml template/config with EVM/JSON-RPC/TLS/Lumera sections |
| claiming_faucet/main.go | Uses EVM keyring options + registers EVM crypto interfaces |
| app/wasm.go | Removes wasm-specific ante/posthandler setup from wasm registration |
| app/vm_preinstalls_test.go | Adds EVM preinstall validation matrix test |
| app/upgrades/v1_12_0/upgrade_test.go | Tests ERC20 params init when InitGenesis skipped |
| app/upgrades/v1_12_0/upgrade.go | Adds v1.12.0 EVM store upgrades + manual params finalization |
| app/upgrades/upgrades_test.go | Adds v1.12.0 to upgrade registry tests |
| app/upgrades/upgrades.go | Registers v1.12.0 upgrade config |
| app/upgrades/store_upgrade_manager_test.go | Adds adaptive store upgrade test for missing EVM stores |
| app/upgrades/store_upgrade_manager.go | Uses shared EnvBool helper |
| app/upgrades/params/params.go | Extends upgrade params with EVM-related keepers |
| app/test_support.go | Import ordering tweak |
| app/test_helpers.go | Adds EVM test-tag guard + denom metadata in genesis + disables fastnode in tests |
| app/statedb_events_test.go | Adds StateDB snapshot/event revert invariant test |
| app/proto_bridge_test.go | Tests proto enum bridge registrations |
| app/proto_bridge.go | Registers Cosmos SDK + EVM enums in proto bridge |
| app/precisebank_mint_burn_parity_test.go | Adds precisebank mint/burn parity tests |
| app/precisebank_fractional_test.go | Adds precisebank fractional balance matrix tests |
| app/pending_tx_listener_test.go | Tests pending tx listener fanout + offline broadcaster error |
| app/openrpc/spec.go | Embeds and serves gzipped OpenRPC spec |
| app/openrpc/rpc_api.go | Exposes rpc.discover service |
| app/openrpc/register.go | Registers rpc namespace on JSON-RPC server |
| app/openrpc/openrpc_test.go | Validates embedded OpenRPC doc and helpers |
| app/ibc_erc20_middleware_test.go | Tests ERC20 IBC middleware wiring (v1/v2) |
| app/ibc.go | Wires ERC20 middleware into IBC transfer stacks |
| app/evm_test.go | Tests EVM module genesis + ordering + module account perms |
| app/evm_static_precompiles_test.go | Tests static precompile registration |
| app/evm_runtime.go | Captures clientCtx via RegisterTxService + shuts down background workers |
| app/evm_mempool_test.go | Tests EVM mempool wiring |
| app/evm_mempool.go | Configures app-side EVM mempool + signer extraction |
| app/evm_jsonrpc_alias.go | Adds JSON-RPC alias reverse proxy + method rewrite |
| app/evm_erc20_policy_msg.go | Implements governance msg server for ERC20 IBC policy |
| app/evm/testtag_guard.go | Adds guard helpers for missing -tags=test |
| app/evm/reset_testbuild.go | Resets EVM global config in test builds |
| app/evm/reset.go | Panics with guidance in non-test builds under testing |
| app/evm/prod_guard_test.go | Documents guard behavior in !test builds |
| app/evm/precompiles.go | Defines Lumera static precompile address list |
| app/evm/modules.go | Registers EVM modules for CLI default genesis generation |
| app/evm/genesis.go | Defines Lumera EVM/feemarket genesis overrides |
| app/evm/defaults_testbuild.go | No-op keeper defaults in test builds |
| app/evm/defaults_prod.go | Sets keeper default coin info in production builds |
| app/evm/config_modules_genesis_test.go | Tests EVM config helpers + genesis overrides + module registration |
| app/evm/config.go | Adds custom signer provider helper |
| app/evm/ante_sigverify_test.go | Tests signature gas consumer matrix |
| app/evm/ante_nonce_test.go | Tests EVM nonce increment matrix |
| app/evm/ante_internal_test.go | Tests genesis-skip decorator behavior |
| app/evm/ante_gas_wanted_test.go | Tests EVM gas-wanted decorator behavior |
| app/evm/ante_evmigration_fee_test.go | Tests reduced ante path for migration-only txs |
| app/encoding.go | Uses EVM test-tag guard when building encoding config in tests |
| app/blocked_addresses_test.go | Tests blocked module/precompile addresses and send restriction |
| app/params/proto.go | Removes legacy encoding config helper |
| app/amino_codec_test.go | Adds legacy amino codec regression test for eth_secp256k1 |
| app/amino_codec.go | Registers eth_secp256k1 amino types + syncs legacy codec |
| ante/evmigration_validate_basic_decorator_test.go | Tests ValidateBasic suppression for migration-only txs |
| ante/evmigration_validate_basic_decorator.go | Allows ErrNoSignatures for migration-only txs |
| ante/evmigration_fee_decorator_test.go | Tests fee waiving for migration-only txs |
| ante/evmigration_fee_decorator.go | Clears min-gas-prices for migration-only txs |
| ante/delayed_claim_fee_decorator.go | Removes disabled decorator block comment |
| Makefile | Adds OpenRPC generation, updates lint tool path, adjusts test targets |
| CHANGELOG.md | Adds v1.12.0 changelog entry + fixes formatting issue |
| .vscode/settings.json | Adds terminal tool auto-approve entry |
| .vscode/launch.json | Adds integration test debug configuration |
| .markdownlint.json | Adds markdownlint overrides |
| .golangci.yml | Adds golangci-lint v2 configuration |
| .github/workflows/test.yml | Switches to make targets + reusable ignite action |
| .github/workflows/systemtests.yml | Adds systemtests workflow using shared actions/make targets |
| .github/workflows/systemtests.yaml | Removes old systemtests workflow |
| .github/workflows/release.yml | Simplifies release workflow to reuse build workflow |
| .github/workflows/lint.yml | Adds a dedicated golangci-lint workflow |
| .github/workflows/build.yml | Adds build workflow orchestrating lint/tests/build+artifacts |
| .github/actions/install-ignite/action.yml | Sets default Ignite version input |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
All 9 previously identified issues are resolved. The three security audit findings (rate-limit proxy bypass, redelegation undercount, chain ID domain separation) have been addressed correctly with well-structured code and comprehensive tests. No new issues found.
Cosmos EVM Integration
Summary
First-class Cosmos EVM integration for Lumera, adding full Ethereum transaction execution, JSON-RPC, EIP-1559 fee market, ERC20/IBC middleware, custom module precompiles, and a purpose-built legacy account migration module — the most comprehensive pre-mainnet EVM integration in the Cosmos ecosystem.
Ships with ~406 EVM-related tests, 19 bugs found and fixed during integration, production-grade operational controls, and features no other Cosmos EVM chain offers: async broadcast queue (deadlock fix), CosmWasm+EVM coexistence, OpenRPC discovery, governance-controlled IBC ERC20 policy, and a full account migration module with dual-signature verification.
Full technical documentation:
docs/evm-integration/main.mdNew Modules
x/vm(Cosmos EVM v0.6.0)x/feemarket0.0005 ulume/gas) and ~6.25% per-block adjustmentx/precisebankulume↔ 18-decimalalumebridge:EVMBalance(a) = I(a) × 10¹² + F(a)x/erc20x/evmigrationKey Changes
Runtime & Execution
app/evm/ante.go): deterministic tx routing based onExtensionOptions[0].TypeUrl— Ethereum extension txs route to EVM path (EVMMonoDecorator+ pending tx listener), Cosmos txs route through Lumera + EVM-aware Cosmos decorator chain, with build-tag-guarded production isolation (//go:build !testindefaults_prod.go)app/evm_mempool.go): Ethereum-like sender ordering, nonce-gap handling, same-nonce replacement with bump rules,max_txs=5000enabled by defaultapp/evm_broadcast.go): decouples txpoolrunReorgpromotion from CometBFTCheckTxvia bounded channel + single background worker, preventing mutex re-entry deadlock — a novel fix no other Cosmos EVM chain has publicly addressedRegisterTxServiceoverride (app/evm_runtime.go): captures the local CometBFT client for the broadcast worker, replacing the stale HTTP client from pre-CometBFTSetClientCtxGetSignersforMsgEthereumTx+ safe early-RPC keeper coin info initialization (SetKeeperDefaults) to prevent panics before genesiswasmd v0.61.6and EVM run in the same runtime — Lumera is the only Cosmos chain shipping both simultaneouslyChain Configuration
76857769eth_secp256k1(default), BIP44 coin type60— MetaMask/Ledger compatible out of the box0.0025 ulume/gas, min gas price floor0.0005 ulume/gas(prevents zero-fee spam that hit Evmos), change denominator16(~6.25%/block vs upstream8at ~12.5%)25,000,000config/bank_metadata.go):ulume/lume/alumemetadata +RegisterExtraInterfacesforeth_secp256k1crypto across all SDK+EVM pathscmd/lumera/cmd/config_migrate.go): pre-EVMapp.tomlfiles auto-gain[evm],[json-rpc], and[evm.mempool]sections with correct chain ID on first startup — no manual interventionPrecompiles (10 static)
Standard (8): P256, Bech32, Staking, Distribution, ICS20, Bank, Gov, Slashing
Action module (
0x0000000000000000000000000000000000000901):requestCascadefinalizeCascaderequestSensefinalizeSenseapproveActiongetActiongetActionFeegetParamsgetActionsByStategetActionsByCreatorgetActionsBySuperNodeSupernode module (
0x0000000000000000000000000000000000000902):registerSupernodederegisterSupernodestartSupernode/stopSupernodeupdateSupernodereportMetricsgetSuperNodegetSuperNodeByAccountlistSuperNodesgetTopSuperNodesForBlockgetMetricsgetParamsPrecompile protections: blocked-address send restrictions on all 10 precompile addresses + module accounts
IBC & Cross-Chain
IBC ERC20 middleware wired on both v1 and v2 transfer stacks:
v1: EVMTransferKeeper → ERC20IBCMiddleware → CallbacksMiddleware → PFM
v2: TransferV2Module → CallbacksV2Middleware → ERC20IBCMiddlewareV2
Governance-controlled registration policy via
MsgSetRegistrationPolicy: 3 modes (all/allowlistdefault/none) with channel-independent base-denom allowlisting (default: uatom, uosmo, uusdc)JSON-RPC & Tooling
eth,net,web3,txpool,debug,personal,minernamespaces; mainnet auto-blocksdebug/personal/adminviajsonrpc_policy.goapp/evm_jsonrpc_ratelimit.go): token bucket proxy —requests-per-second=50,burst=100,entry-ttl=5m, HTTP 429 with JSON-RPC-32005on limit, stale entries GC'd every 60sapp.toml [evm] tracer—json,struct,access_list,markdown; enablesdebug_traceTransaction,debug_traceBlockByNumber,debug_traceBlockByHash,debug_traceCallrpc_discoverJSON-RPC method (port 8545) +GET/POST /openrpc.jsonHTTP endpoint (port 1317) with CORS; gzip-compressed spec embedded in binary (315 KB → 20 KB); build-time generation viatools/openrpcgenwith Go reflection + AST parsing;POST /openrpc.jsonproxies to JSON-RPC server enabling OpenRPC Playground "Try It" directly; spec version fromgo.modviaruntime/debug.ReadBuildInfo()https://playground.open-rpc.org/?url=http://<node>:1317/openrpc.jsonAccount Migration (
x/evmigration)MsgClaimLegacyAccount: signed by neweth_secp256k1address; legacy signature =secp256k1_sign(SHA256("lumera-evm-migration:<legacy_address>:<new_address>"))MsgMigrateValidator: re-keys validator record + all associated module state including delegator referencesante/evmigration_fee_decorator.go): zero-fee migration txs since new address has no balanceenable_migration,migration_end_time,max_migrations_per_block=50,max_validator_delegations=2000MigrationRecord,MigrationRecords,MigrationEstimate(dry-run),MigrationStats,LegacyAccounts,MigratedAccountsUpgrade & Ops
feemarket,precisebank,vm,erc20,evmigration; post-migration finalization sets Lumera EVM params + coin info, feemarket params, ERC20 defaults (EnableErc20=true,PermissionlessRegistration=true)docs/evm-integration/node-evm-config-guide.md—app.tomltuning,[evm]/[json-rpc]/[evm.mempool]sections, RPC exposure, tracer config, rate limiting, security policiesDevnet
devnet/default-config/devnet-genesis-evm.json)devnet/tests/validator/evm_test.go): fee market, cross-peer tx visibility, mixed Cosmos+EVM blocksdocs/evm-integration/remix-guide.md— MetaMask network config, contract deployment, interaction, event querying, troubleshootingBugs Found & Fixed (19 issues)
Documented in
docs/evm-integration/bugs.mdTest Coverage (~406 tests)
all/allowlist/none), v1+v2 stacksnewHeads,logs,pendingTransactionsDevnet evmigration pipeline (
make devnet-evm-upgrade): boots v1.11.0 devnet → prepares legacy state (5 legacy + 5 extra accounts with delegations, unbonding, redelegations, authz, feegrant, supernode, action across all validators) → governance upgrade to v1.12.0 → estimate all accounts → migrate validators → migrate accounts → verify clean state. Idempotent and rerunnable.Documentation Added
main.mdtests.mdbugs.mdroadmap.mdnode-evm-config-guide.mdapp.tomltuning, security policies, rate limitingopenrpc-playground.mdremix-guide.mdaction-precompile.md0x0901) ABI reference, 11 methods, design notessupernode-precompile.md0x0902) ABI reference, 12 methods, design notesdevnet-tests.mdlumera-ports.mdWhat Makes This Different
rpc_discover+/openrpc.json+ playground proxy0.0005 ulume/gas(prevents decay to zero)all/allowlist/none0x0901) + Supernode (0x0902) at launchconfig_migrate.goadds[evm]section on startupGas Configuration
Roadmap Status
155/163 items complete (95%) across 15 phases.
Breaking Changes
secp256k1eth_secp256k1keys adddefaults to Ethereum-compatible keys11860feemarket,precisebank,vm,erc20,evmigration[evm]section[evm],[json-rpc],[evm.mempool]inapp.tomlconfig_migrate.goTest Plan
make devnet-new— boots 3-validator EVM devnet, processes mixed Cosmos+EVM blocksmake devnet-evm-upgrade— v1.11.0 → v1.12.0 with full evmigration cycle (prepare → estimate → migrate-validator → migrate → verify)76857769), sends EVM tx, tx confirmed on-chain/openrpc.json,rpc_discoverreturns full spec0x0901):requestCascade→approveAction→finalizeCascaderound-trip0x0902):registerSupernode→reportMetrics→getSuperNoderound-trip