diff --git a/.goreleaser.yml b/.goreleaser.yml index c6b3cd7f..324536cd 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -96,11 +96,54 @@ builds: hooks: pre: - wget -O /lib/libwasmvm_muslc.x86_64.a https://github.com/CosmWasm/wasmvm/releases/download/{{ .Env.COSMWASM_VERSION }}/libwasmvm_muslc.x86_64.a - - echo "a4a3d09b36fabb65b119d5ba23442c23694401fcbee4451fe6b7e22e325a4bac /lib/libwasmvm_muslc.x86_64.a" | sha256sum -c + - echo "cefe73f0caa5a9eaba3733c639cdf5040c4746a93c20670ba6c9287fe39448ba /lib/libwasmvm_muslc.x86_64.a" | sha256sum -c - cp /lib/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.a - - curl -LO https://musl.cc/x86_64-linux-musl-cross.tgz - - tar xf x86_64-linux-musl-cross.tgz - - mv x86_64-linux-musl-cross /opt/musl-cross + - curl -L -o /opt/x86_64-linux-musl-cross.tgz https://musl.cc/x86_64-linux-musl-cross.tgz + - tar xf /opt/x86_64-linux-musl-cross.tgz -C /opt + - rm -f /opt/x86_64-linux-musl-cross.tgz + - mv /opt/x86_64-linux-musl-cross /opt/musl-cross + ldflags: + - -s -w + - -linkmode=external + - -extldflags "-Wl,-z,muldefs -static" + - -X main.commit={{.Commit}} + - -X main.date={{ .CommitDate }} + - -X github.com/cosmos/cosmos-sdk/version.Name=kiichain + - -X github.com/cosmos/cosmos-sdk/version.AppName=kiichaind + - -X github.com/cosmos/cosmos-sdk/version.Version=v{{ .Version }} + - -X github.com/cosmos/cosmos-sdk/version.Commit={{ .Commit }} + - -X github.com/cosmos/cosmos-sdk/version.BuildTags=muslc,ledger + - -X github.com/cometbft/cometbft/version.TMCoreSemVer={{ .Env.TM_VERSION }} + + - id: kiichaind-linux-arm64 + main: ./cmd/kiichaind + binary: kiichaind + builder: go + gobinary: "go" + env: + - CGO_ENABLED=1 + - CC=/opt/musl-cross-arm64/bin/aarch64-linux-musl-gcc + - LD=/opt/musl-cross-arm64/bin/aarch64-linux-musl-ld + # Isolated -L dir so this does not clobber the amd64 build running in parallel + - CGO_LDFLAGS=-L/lib/aarch64 + goos: + - linux + goarch: + - arm64 + mod_timestamp: "{{ .CommitTimestamp }}" + tags: + - muslc + - ledger + hooks: + pre: + - mkdir -p /lib/aarch64 + - wget -O /lib/aarch64/libwasmvm_muslc.aarch64.a https://github.com/CosmWasm/wasmvm/releases/download/{{ .Env.COSMWASM_VERSION }}/libwasmvm_muslc.aarch64.a + - echo "a04969b4f931be1d2e2f3f2313a68a20a202693f67559f7aaf1dd97250823aec /lib/aarch64/libwasmvm_muslc.aarch64.a" | sha256sum -c + - cp /lib/aarch64/libwasmvm_muslc.aarch64.a /lib/aarch64/libwasmvm_muslc.a + - curl -L -o /opt/aarch64-linux-musl-cross.tgz https://musl.cc/aarch64-linux-musl-cross.tgz + - tar xf /opt/aarch64-linux-musl-cross.tgz -C /opt + - rm -f /opt/aarch64-linux-musl-cross.tgz + - mv /opt/aarch64-linux-musl-cross /opt/musl-cross-arm64 ldflags: - -s -w - -linkmode=external @@ -144,6 +187,7 @@ archives: - kiichaind-darwin-arm64 - kiichaind-darwin-amd64 - kiichaind-linux-amd64 + - kiichaind-linux-arm64 wrap_in_directory: false files: - none* diff --git a/CHANGELOG.md b/CHANGELOG.md index 23437cee..b9f07f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Dependencies - [EVM](https://github.com/KiiChain/evm) fork from v0.6.0-fork.1 to [v0.6.0-fork.2](https://github.com/KiiChain/evm/releases/tag/v0.6.0-fork.2): bounded internal EVM call gas limit, EVM fee refunds, distribution precompile 32-byte withdraw fix, and CosmWasm EVM query undercharge fix +- [EVM](https://github.com/KiiChain/evm) fork bump from `v0.6.0-fork.2` to [v0.6.1-fork.1](https://github.com/KiiChain/evm/releases/tag/v0.6.1-fork.1), applied via the coordinated `v7.3.0` upgrade: the July 2026 Cosmos EVM hotfix (precompile gas accounting alignment and StateDB locked-balance snapshotting), published upstream as [cosmos/evm v0.6.1](https://github.com/cosmos/evm/releases/tag/v0.6.1) ### Added diff --git a/Makefile b/Makefile index 94a4360f..cc2dc35c 100644 --- a/Makefile +++ b/Makefile @@ -148,6 +148,7 @@ distclean: clean GO_VERSION := $(shell cat go.mod | grep -E 'go [0-9].[0-9]+' | cut -d ' ' -f 2) GORELEASER_IMAGE := ghcr.io/goreleaser/goreleaser-cross:v$(REQUIRE_GO_VERSION) COSMWASM_VERSION := $(shell go list -m github.com/CosmWasm/wasmvm/v3 | sed 's/.* //') +GOMODCACHE := $(shell go env GOMODCACHE) # create tag and run goreleaser without publishing # errors are possible while running goreleaser - the process can run for >30 min @@ -162,12 +163,15 @@ ifneq ($(strip $(TAG)),) @git tag -d $(TAG) @echo "--> Running goreleaser" @go install github.com/goreleaser/goreleaser@latest + @go mod download @docker run \ --rm \ -e CGO_ENABLED=1 \ + -e GOMODCACHE=/go/pkg/mod \ -e TM_VERSION=$(TM_VERSION) \ -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ -v `pwd`:/go/src/kiichaind \ + -v $(GOMODCACHE):/go/pkg/mod:ro \ -w /go/src/kiichaind \ $(GORELEASER_IMAGE) \ release \ @@ -203,36 +207,41 @@ build-static-linux-amd64: go.sum $(BUILDDIR)/ # uses goreleaser to create static binaries for darwin on local machine goreleaser-build-local: + go mod download docker run \ --rm \ -e CGO_ENABLED=1 \ + -e GOMODCACHE=/go/pkg/mod \ -e TM_VERSION=$(TM_VERSION) \ -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ -v `pwd`:/go/src/kiichaind \ + -v $(GOMODCACHE):/go/pkg/mod:ro \ -w /go/src/kiichaind \ $(GORELEASER_IMAGE) \ release \ --snapshot \ --skip=publish \ - --release-notes ./RELEASE_NOTES.md \ --timeout 90m \ - --verbose + --verbose \ + --clean # uses goreleaser to create static binaries for linux an darwin # requires access to GITHUB_TOKEN which has to be available in the CI environment ifdef GITHUB_TOKEN ci-release: + go mod download docker run \ --rm \ -e CGO_ENABLED=1 \ -e GITHUB_TOKEN=$(GITHUB_TOKEN) \ + -e GOMODCACHE=/go/pkg/mod \ -e TM_VERSION=$(TM_VERSION) \ -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ -v `pwd`:/go/src/kiichaind \ + -v $(GOMODCACHE):/go/pkg/mod:ro \ -w /go/src/kiichaind \ $(GORELEASER_IMAGE) \ release \ - --release-notes ./RELEASE_NOTES.md \ --timeout=90m \ --clean else diff --git a/app/app.go b/app/app.go index c3db6222..162c5089 100644 --- a/app/app.go +++ b/app/app.go @@ -68,7 +68,7 @@ import ( kiiante "github.com/kiichain/kiichain/v7/ante" "github.com/kiichain/kiichain/v7/app/keepers" "github.com/kiichain/kiichain/v7/app/upgrades" - v7_2 "github.com/kiichain/kiichain/v7/app/upgrades/v7_2" + v7_3 "github.com/kiichain/kiichain/v7/app/upgrades/v7_3" "github.com/kiichain/kiichain/v7/client/docs" ) @@ -78,7 +78,7 @@ var ( // Upgrades is a list of all the upgrades that are available for the application. Upgrades = []upgrades.Upgrade{ - v7_2.Upgrade, + v7_3.Upgrade, } ) diff --git a/app/apptesting/evm.go b/app/apptesting/evm.go index 5e645b50..4330bdf8 100644 --- a/app/apptesting/evm.go +++ b/app/apptesting/evm.go @@ -9,7 +9,6 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/evm/contracts" erc20types "github.com/cosmos/evm/x/erc20/types" @@ -18,10 +17,37 @@ import ( app "github.com/kiichain/kiichain/v7/app" ) -// DeployERC20 deploys an ERC20 contract +// ERC20DeployerSeed is used to derive a deterministic non-module deployer for +// test ERC20 deployments. Module accounts cannot receive balance updates via +// SetBalanceWithLocked after the Cosmos EVM locked-balance hotfix. +const ERC20DeployerSeed = "kiichain/apptesting/erc20-deployer" + +// ERC20DeployerAddress returns the deterministic EOA used to deploy/mint test +// ERC20 contracts. +func ERC20DeployerAddress() common.Address { + seed := crypto.Keccak256([]byte(ERC20DeployerSeed)) + key, err := crypto.ToECDSA(seed) + if err != nil { + panic(err) + } + return crypto.PubkeyToAddress(key.PublicKey) +} + +// DefaultFirstERC20 is the contract address produced by the first DeployERC20 +// call (deployer nonce 0). +var DefaultFirstERC20 = crypto.CreateAddress(ERC20DeployerAddress(), 0).Hex() + +// ensureAccountExists creates the account if missing so nonce tracking works. +func ensureAccountExists(ctx sdk.Context, app *app.KiichainApp, addr sdk.AccAddress) { + if app.AccountKeeper.GetAccount(ctx, addr) == nil { + app.AccountKeeper.SetAccount(ctx, app.AccountKeeper.NewAccountWithAddress(ctx, addr)) + } +} + +// DeployERC20 deploys an ERC20 contract from a deterministic non-module EOA. func DeployERC20(ctx sdk.Context, app *app.KiichainApp) (common.Address, error) { - // Select the from as the erc20 module address - from := common.BytesToAddress(authtypes.NewModuleAddress(erc20types.ModuleName).Bytes()) + from := ERC20DeployerAddress() + ensureAccountExists(ctx, app, sdk.AccAddress(from.Bytes())) // Set the data erc20ABI := contracts.ERC20MinterBurnerDecimalsContract.ABI @@ -47,10 +73,11 @@ func DeployERC20(ctx sdk.Context, app *app.KiichainApp) (common.Address, error) return contractAddr, nil } -// MintERC20 mints an ERC20 token +// MintERC20 mints an ERC20 token using the same deployer EOA that owns the +// contract from DeployERC20. func MintERC20(ctx sdk.Context, app *app.KiichainApp, contractAddr common.Address, to common.Address, amount *big.Int) error { - // Sender must be an account with ETH balance and nonce tracking - from := common.BytesToAddress(authtypes.NewModuleAddress(erc20types.ModuleName).Bytes()) + from := ERC20DeployerAddress() + ensureAccountExists(ctx, app, sdk.AccAddress(from.Bytes())) // Load the ABI and pack the mint() call erc20ABI := contracts.ERC20MinterBurnerDecimalsContract.ABI @@ -71,14 +98,13 @@ func MintERC20(ctx sdk.Context, app *app.KiichainApp, contractAddr common.Addres // CreateERC20Allowance creates an ERC20 allowance func CreateERC20Allowance(ctx sdk.Context, app *app.KiichainApp, contractAddr common.Address, owner common.Address, spender common.Address, amount *big.Int) error { - // Load the ABI and pack the mint() call + // Load the ABI and pack the approve() call erc20ABI := contracts.ERC20MinterBurnerDecimalsContract.ABI inputData, err := erc20ABI.Pack("approve", spender, amount) if err != nil { return err } - // Send transaction to call mint stateDB := statedb.New(ctx, app.EVMKeeper, statedb.NewEmptyTxConfig()) _, err = app.EVMKeeper.CallEVMWithData(ctx, stateDB, owner, &contractAddr, inputData, true, false, nil) if err != nil { diff --git a/app/upgrades/v7_2/constants.go b/app/upgrades/v7_2/constants.go deleted file mode 100644 index 55dfe269..00000000 --- a/app/upgrades/v7_2/constants.go +++ /dev/null @@ -1,17 +0,0 @@ -package v720 - -import ( - "github.com/kiichain/kiichain/v7/app/upgrades" -) - -const ( - // UpgradeName is the name of the upgrade - UpgradeName = "v7.2.0" -) - -// Upgrade defines the upgrade, running module migrations to backfill the -// tokenfactory admin secondary index. -var Upgrade = upgrades.Upgrade{ - UpgradeName: UpgradeName, - CreateUpgradeHandler: CreateUpgradeHandler, -} diff --git a/app/upgrades/v7_3/constants.go b/app/upgrades/v7_3/constants.go new file mode 100644 index 00000000..5b8bff35 --- /dev/null +++ b/app/upgrades/v7_3/constants.go @@ -0,0 +1,20 @@ +package v730 + +import ( + "github.com/kiichain/kiichain/v7/app/upgrades" +) + +const ( + // UpgradeName is the name of the upgrade + UpgradeName = "v7.3.0" +) + +// Upgrade defines the coordinated upgrade for the EVM v0.6.1-fork.1 dependency +// bump. Those changes (precompile gas accounting, statedb locked-balance +// handling, and feemarket EndBlock) are state-machine-breaking, so this upgrade +// ensures every validator switches to the new binary at the same height. No +// store migrations are required. +var Upgrade = upgrades.Upgrade{ + UpgradeName: UpgradeName, + CreateUpgradeHandler: CreateUpgradeHandler, +} diff --git a/app/upgrades/v7_2/upgrade.go b/app/upgrades/v7_3/upgrade.go similarity index 60% rename from app/upgrades/v7_2/upgrade.go rename to app/upgrades/v7_3/upgrade.go index b1b5d644..f11e4e7b 100644 --- a/app/upgrades/v7_2/upgrade.go +++ b/app/upgrades/v7_3/upgrade.go @@ -1,4 +1,4 @@ -package v720 +package v730 import ( "context" @@ -11,9 +11,10 @@ import ( "github.com/kiichain/kiichain/v7/app/keepers" ) -// CreateUpgradeHandler creates the upgrade handler for the v7.2.0 upgrade. -// It runs all pending module migrations, which includes the tokenfactory v1→v2 -// migration that backfills the secondary admin index. +// CreateUpgradeHandler creates the upgrade handler for the v7.3.0 upgrade. +// This upgrade coordinates the switch to the EVM v0.6.1-fork.1 dependency, whose +// changes are state-machine-breaking. No custom state migrations are needed, so +// the handler only runs pending module migrations. func CreateUpgradeHandler( mm *module.Manager, configurator module.Configurator, @@ -22,14 +23,14 @@ func CreateUpgradeHandler( return func(c context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { ctx := sdk.UnwrapSDKContext(c) - ctx.Logger().Info("Starting module migrations for v7.2.0...") + ctx.Logger().Info("Starting module migrations for v7.3.0...") vm, err := mm.RunMigrations(ctx, configurator, vm) if err != nil { return vm, err } - ctx.Logger().Info("Upgrade v7.2.0 complete") + ctx.Logger().Info("Upgrade v7.3.0 complete") return vm, nil } } diff --git a/go.mod b/go.mod index 69d52ff8..b8fdcd6e 100644 --- a/go.mod +++ b/go.mod @@ -312,7 +312,7 @@ replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 // Use our fork w/ fee abstraction possibility - github.com/cosmos/evm => github.com/KiiChain/evm v0.6.0-fork.2 + github.com/cosmos/evm => github.com/KiiChain/evm v0.6.1-fork.1 // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 diff --git a/go.sum b/go.sum index f2d2b9a5..9d3626f3 100644 --- a/go.sum +++ b/go.sum @@ -705,8 +705,8 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= -github.com/KiiChain/evm v0.6.0-fork.2 h1:OHk0OI5hIYbHHMWCESHCROErdMcJlofLgpQ6p0TdNmA= -github.com/KiiChain/evm v0.6.0-fork.2/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= +github.com/KiiChain/evm v0.6.1-fork.1 h1:o6kbWW26YbiSW2NSAIi1Nf1Cty66HvXm60Ki5hzb7Uo= +github.com/KiiChain/evm v0.6.1-fork.1/go.mod h1:QnaJDtxqon2mywiYqxM8VwW8FKeFazi0au0qzVpFAG8= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= diff --git a/wasmbinding/evm/reflect_query_test.go b/wasmbinding/evm/reflect_query_test.go index 3b1ae2a5..d8a5ad26 100644 --- a/wasmbinding/evm/reflect_query_test.go +++ b/wasmbinding/evm/reflect_query_test.go @@ -12,9 +12,7 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - erc20types "github.com/cosmos/evm/x/erc20/types" "github.com/cosmos/evm/x/vm/statedb" app "github.com/kiichain/kiichain/v7/app" @@ -205,8 +203,10 @@ func TestQueryERC20Allowance(t *testing.T) { // deployCounter deploys the counter contract func deployCounter(t *testing.T, ctx sdk.Context, app *app.KiichainApp) common.Address { t.Helper() - // Select the from as the erc20 module address - from := common.BytesToAddress(authtypes.NewModuleAddress(erc20types.ModuleName).Bytes()) + from := apptesting.ERC20DeployerAddress() + if app.AccountKeeper.GetAccount(ctx, sdk.AccAddress(from.Bytes())) == nil { + app.AccountKeeper.SetAccount(ctx, app.AccountKeeper.NewAccountWithAddress(ctx, sdk.AccAddress(from.Bytes()))) + } // Set the data counterABI, err := mock.CounterMetaData.GetAbi() @@ -230,8 +230,10 @@ func deployCounter(t *testing.T, ctx sdk.Context, app *app.KiichainApp) common.A // incrementCounter increments the counter in the contract func incrementCounter(t *testing.T, ctx sdk.Context, app *app.KiichainApp, contractAddr common.Address) { t.Helper() - // Sender must be an account with ETH balance and nonce tracking - from := common.BytesToAddress(authtypes.NewModuleAddress(erc20types.ModuleName).Bytes()) + from := apptesting.ERC20DeployerAddress() + if app.AccountKeeper.GetAccount(ctx, sdk.AccAddress(from.Bytes())) == nil { + app.AccountKeeper.SetAccount(ctx, app.AccountKeeper.NewAccountWithAddress(ctx, sdk.AccAddress(from.Bytes()))) + } // Load the ABI and pack the increment() call counterABI, err := mock.CounterMetaData.GetAbi() diff --git a/x/feeabstraction/ante/cosmos/fee_test.go b/x/feeabstraction/ante/cosmos/fee_test.go index d78a8266..22e7aa76 100644 --- a/x/feeabstraction/ante/cosmos/fee_test.go +++ b/x/feeabstraction/ante/cosmos/fee_test.go @@ -31,7 +31,7 @@ import ( ) var ( - DefaultFirstERC20 = "0x80b5a32E4F032B2a058b4F29EC95EEfEEB87aDcd" + DefaultFirstERC20 = apptesting.DefaultFirstERC20 DefaultFirstERC20Denom = "erc20:" + DefaultFirstERC20 DefaultMinFeeValue = int64(875000000000000) diff --git a/x/feeabstraction/keeper/fee_test.go b/x/feeabstraction/keeper/fee_test.go index 8edb6c2b..24670d03 100644 --- a/x/feeabstraction/keeper/fee_test.go +++ b/x/feeabstraction/keeper/fee_test.go @@ -25,8 +25,8 @@ func (s *KeeperTestSuite) TestConvertNativeFee() { feePayer := apptesting.RandomAccountAddress() s.app.AccountKeeper.SetAccount(s.ctx, s.app.AccountKeeper.NewAccountWithAddress(s.ctx, feePayer)) - // Default erc20 address to use in tests - DefaultFirstERC20 := "0x80b5a32E4F032B2a058b4F29EC95EEfEEB87aDcd" + // Default erc20 address to use in tests (first DeployERC20 from apptesting deployer) + DefaultFirstERC20 := apptesting.DefaultFirstERC20 // Reactivate keeper since it was disabled on abci err := s.app.FeeAbstractionKeeper.Params.Set(s.ctx, types.DefaultParams())