From 726efa6d328fffc4c32acc216d50dec2d5fa8d0a Mon Sep 17 00:00:00 2001 From: Nilesh Gupta Date: Mon, 7 Sep 2026 17:11:18 +0530 Subject: [PATCH 1/2] chore: add evm-v0.6.3 upgrade handler (donut) No state migration; the plan name lets cosmovisor swap the binary at a coordinated height, which the gasless MsgVoteReadResult change requires. --- app/upgrades.go | 2 + app/upgrades/evm-v0-6-3/upgrade.go | 77 ++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 app/upgrades/evm-v0-6-3/upgrade.go diff --git a/app/upgrades.go b/app/upgrades.go index af46db44..3c489f14 100755 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -24,6 +24,7 @@ import ( evmv050 "github.com/pushchain/push-chain-node/app/upgrades/evm-v0-5-0" evmv060 "github.com/pushchain/push-chain-node/app/upgrades/evm-v0-6-0" evmv062 "github.com/pushchain/push-chain-node/app/upgrades/evm-v0-6-2" + evmv063 "github.com/pushchain/push-chain-node/app/upgrades/evm-v0-6-3" feeabs "github.com/pushchain/push-chain-node/app/upgrades/fee-abs" gasoracle "github.com/pushchain/push-chain-node/app/upgrades/gas-oracle" "github.com/pushchain/push-chain-node/app/upgrades/noop" @@ -100,6 +101,7 @@ var Upgrades = []upgrades.Upgrade{ // read-state — adds the x/ucallback store and reserves every system-contract // address still unclaimed in the A/B/C ranges (41 of 47 on donut, incl. 0xC2) readstate.NewUpgrade(), + evmv063.NewUpgrade(), } // RegisterUpgradeHandlers registers the chain upgrade handlers diff --git a/app/upgrades/evm-v0-6-3/upgrade.go b/app/upgrades/evm-v0-6-3/upgrade.go new file mode 100644 index 00000000..8fd35635 --- /dev/null +++ b/app/upgrades/evm-v0-6-3/upgrade.go @@ -0,0 +1,77 @@ +package evmv063 + +import ( + "context" + "fmt" + + storetypes "cosmossdk.io/store/types" + upgradetypes "cosmossdk.io/x/upgrade/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/pushchain/push-chain-node/app/upgrades" +) + +const UpgradeName = "evm-v0.6.3" + +// NewUpgrade registers the cosmos/evm v0.6.2 -> v0.6.3 bump plus the read-state +// fixes that landed alongside it (#366). +// +// No state migration: across v0.6.2..v0.6.3 upstream changed two files, both in +// x/vm/statedb — no .proto, no store key, no ConsensusVersion bump. The +// push-chain changes add no store and no proto either. StoreUpgrades is empty and +// RunMigrations is expected to be a no-op; the handler exists so the plan has a +// name for cosmovisor to switch the binary on. +// +// The consensus-affecting changes carried by this binary, for the record: +// +// cosmos/evm v0.6.3: +// - statedb AddBalance now panics on overflow instead of wrapping silently +// (the counterpart to the SubBalance underflow fix in v0.6.2). +// - StateDB.Commit is now atomic. The precompile path folded its dirty set into +// the root ctx while the precompile writes went to the cache, so the two could +// diverge; both now land in the same context. The normal path stages through a +// cache context, so a failure part-way leaves ctx untouched rather than +// half-written. +// +// push-chain (#366): +// - MsgVoteReadResult is gasless. This is the reason the upgrade must be +// height-coordinated: an old binary still deducts the fee, so the two disagree +// on state and the app hash diverges. +// - x/ucallback passes explicit gas limits instead of nil, which made the EVM +// estimate and land on gas that starved the callback it was funding. +// - Reads requested inside a UEA payload are now ingested. They run through +// DerivedEVMCall, which never fires the post-tx hook, so the request was +// emitted and escrowed with nothing recording it. +func NewUpgrade() upgrades.Upgrade { + return upgrades.Upgrade{ + UpgradeName: UpgradeName, + CreateUpgradeHandler: CreateUpgradeHandler, + StoreUpgrades: storetypes.StoreUpgrades{ + Added: []string{}, + Deleted: []string{}, + }, + } +} + +// CreateUpgradeHandler runs the standard module migrations. None is expected to +// fire; RunMigrations is called anyway so the stored version map stays consistent +// and any migration bundled by a dependency still executes rather than being +// silently skipped. +func CreateUpgradeHandler( + mm upgrades.ModuleManager, + configurator module.Configurator, + _ *upgrades.AppKeepers, +) upgradetypes.UpgradeHandler { + return func(ctx context.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + logger := sdk.UnwrapSDKContext(ctx).Logger().With("upgrade", UpgradeName) + logger.Info("starting cosmos/evm v0.6.3 upgrade: no state migration expected") + + versionMap, err := mm.RunMigrations(ctx, configurator, fromVM) + if err != nil { + return nil, fmt.Errorf("run migrations: %w", err) + } + + logger.Info("cosmos/evm v0.6.3 upgrade complete") + return versionMap, nil + } +} From 2d70997eeff66fd83b0e130118852be4ce2d2d02 Mon Sep 17 00:00:00 2001 From: Nilesh Gupta Date: Mon, 7 Sep 2026 17:19:32 +0530 Subject: [PATCH 2/2] chore: trim handler comments --- app/upgrades/evm-v0-6-3/upgrade.go | 37 +++--------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/app/upgrades/evm-v0-6-3/upgrade.go b/app/upgrades/evm-v0-6-3/upgrade.go index 8fd35635..574f32c0 100644 --- a/app/upgrades/evm-v0-6-3/upgrade.go +++ b/app/upgrades/evm-v0-6-3/upgrade.go @@ -13,35 +13,8 @@ import ( const UpgradeName = "evm-v0.6.3" -// NewUpgrade registers the cosmos/evm v0.6.2 -> v0.6.3 bump plus the read-state -// fixes that landed alongside it (#366). -// -// No state migration: across v0.6.2..v0.6.3 upstream changed two files, both in -// x/vm/statedb — no .proto, no store key, no ConsensusVersion bump. The -// push-chain changes add no store and no proto either. StoreUpgrades is empty and -// RunMigrations is expected to be a no-op; the handler exists so the plan has a -// name for cosmovisor to switch the binary on. -// -// The consensus-affecting changes carried by this binary, for the record: -// -// cosmos/evm v0.6.3: -// - statedb AddBalance now panics on overflow instead of wrapping silently -// (the counterpart to the SubBalance underflow fix in v0.6.2). -// - StateDB.Commit is now atomic. The precompile path folded its dirty set into -// the root ctx while the precompile writes went to the cache, so the two could -// diverge; both now land in the same context. The normal path stages through a -// cache context, so a failure part-way leaves ctx untouched rather than -// half-written. -// -// push-chain (#366): -// - MsgVoteReadResult is gasless. This is the reason the upgrade must be -// height-coordinated: an old binary still deducts the fee, so the two disagree -// on state and the app hash diverges. -// - x/ucallback passes explicit gas limits instead of nil, which made the EVM -// estimate and land on gas that starved the callback it was funding. -// - Reads requested inside a UEA payload are now ingested. They run through -// DerivedEVMCall, which never fires the post-tx hook, so the request was -// emitted and escrowed with nothing recording it. +// evm v0.6.2 -> v0.6.3 plus the read-state fixes in #366. No state migration; the +// plan name exists so cosmovisor swaps the binary at a coordinated height. func NewUpgrade() upgrades.Upgrade { return upgrades.Upgrade{ UpgradeName: UpgradeName, @@ -53,10 +26,6 @@ func NewUpgrade() upgrades.Upgrade { } } -// CreateUpgradeHandler runs the standard module migrations. None is expected to -// fire; RunMigrations is called anyway so the stored version map stays consistent -// and any migration bundled by a dependency still executes rather than being -// silently skipped. func CreateUpgradeHandler( mm upgrades.ModuleManager, configurator module.Configurator, @@ -64,7 +33,7 @@ func CreateUpgradeHandler( ) upgradetypes.UpgradeHandler { return func(ctx context.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { logger := sdk.UnwrapSDKContext(ctx).Logger().With("upgrade", UpgradeName) - logger.Info("starting cosmos/evm v0.6.3 upgrade: no state migration expected") + logger.Info("starting cosmos/evm v0.6.3 upgrade") versionMap, err := mm.RunMigrations(ctx, configurator, fromVM) if err != nil {