From 4466ea5121cf8641aea8521e5e71bbe396861c11 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 14 Jan 2025 17:23:05 +0800 Subject: [PATCH 1/9] feat(testutil/sims): add back AppStateFnWithExtendedCbs (#23236) --- testutil/sims/state_helpers.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go index 8e229891c7e7..53385e2c81d8 100644 --- a/testutil/sims/state_helpers.go +++ b/testutil/sims/state_helpers.go @@ -42,6 +42,23 @@ func AppStateFn( addressCodec, validatorCodec address.Codec, modules []module.AppModuleSimulation, genesisState map[string]json.RawMessage, +) simtypes.AppStateFn { + return AppStateFnWithExtendedCbs(cdc, addressCodec, validatorCodec, modules, genesisState, nil, nil) +} + +// AppStateFnWithExtendedCbs returns the initial application state using a genesis or the simulation parameters. +// It panics if the user provides files for both of them. +// If a file is not given for the genesis or the sim params, it creates a randomized one. +// genesisState is the default genesis state of the whole app. +// moduleStateCb is the callback function to access moduleState. +// postRawStateCb is the callback function to extend rawState. +func AppStateFnWithExtendedCbs( + cdc codec.JSONCodec, + addressCodec, validatorCodec address.Codec, + modules []module.AppModuleSimulation, + genesisState map[string]json.RawMessage, + moduleStateCb func(moduleName string, genesisState interface{}), + postRawStateCb func(rawState map[string]json.RawMessage), ) simtypes.AppStateFn { return func( r *rand.Rand, @@ -143,9 +160,17 @@ func AppStateFn( stakingtypes.ModuleName: stakingState, testutil.BankModuleName: bankState, } { + if moduleStateCb != nil { + moduleStateCb(name, state) + } rawState[name] = cdc.MustMarshalJSON(state) } + // extend state from callback function + if postRawStateCb != nil { + postRawStateCb(rawState) + } + // replace appstate appState, err = json.Marshal(rawState) if err != nil { From 5581225a9b0c9b60d825ab470ac63ab989a7e1e7 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 14 Jan 2025 17:40:50 +0800 Subject: [PATCH 2/9] fix(x/upgrade): register missing implementation for SoftwareUpgradeProposal (#23179) --- UPGRADING.md | 20 ++++++++++++++++--- simapp/v2/upgrades.go | 7 ------- tests/systemtests/upgrade_test.go | 2 +- x/upgrade/CHANGELOG.md | 3 +++ x/upgrade/go.mod | 2 +- x/upgrade/types/codec.go | 6 +++++- x/upgrade/types/codec_test.go | 33 +++++++++++++++++++++++++++++++ x/upgrade/types/proposal.go | 21 ++++++++++++++++++++ 8 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 x/upgrade/types/codec_test.go create mode 100644 x/upgrade/types/proposal.go diff --git a/UPGRADING.md b/UPGRADING.md index ae7eae68d94b..f5c621bcc5aa 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -469,9 +469,23 @@ Accounts's AccountNumber will be used as a global account number tracking replac ```go import authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" ... -err := authkeeper.MigrateAccountNumberUnsafe(ctx, &app.AuthKeeper) -if err != nil { - return nil, err +app.UpgradeKeeper.SetUpgradeHandler(planName, + func(ctx context.Context, _ upgradetypes.Plan, fromVM appmodule.VersionMap) (appmodule.VersionMap, error) { + if err := authkeeper.MigrateAccountNumberUnsafe(ctx, &app.AuthKeeper); err != nil { + return nil, err + } + return app.ModuleManager.RunMigrations(ctx, app.configurator, fromVM) + }, +) +``` + +Add `x/accounts` store while upgrading to v0.52.x: + +```go +storetypes.StoreUpgrades{ + Added: []string{ + accounts.StoreKey, + }, } ``` diff --git a/simapp/v2/upgrades.go b/simapp/v2/upgrades.go index 2145196fa86d..20643c129749 100644 --- a/simapp/v2/upgrades.go +++ b/simapp/v2/upgrades.go @@ -6,10 +6,7 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/core/store" "cosmossdk.io/runtime/v2" - "cosmossdk.io/x/accounts" bankv2types "cosmossdk.io/x/bank/v2/types" - epochstypes "cosmossdk.io/x/epochs/types" - protocolpooltypes "cosmossdk.io/x/protocolpool/types" upgradetypes "cosmossdk.io/x/upgrade/types" ) @@ -37,12 +34,8 @@ func (app *SimApp[T]) RegisterUpgradeHandlers() { if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { storeUpgrades := store.StoreUpgrades{ Added: []string{ - accounts.StoreKey, - protocolpooltypes.StoreKey, - epochstypes.StoreKey, bankv2types.ModuleName, }, - Deleted: []string{"crisis"}, // The SDK discontinued the crisis module in v0.52.0 } app.SetStoreLoader(runtime.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) diff --git a/tests/systemtests/upgrade_test.go b/tests/systemtests/upgrade_test.go index 81e2b93f5d61..cc2f8497ecff 100644 --- a/tests/systemtests/upgrade_test.go +++ b/tests/systemtests/upgrade_test.go @@ -37,7 +37,7 @@ func TestChainUpgrade(t *testing.T) { const ( upgradeHeight int64 = 22 - upgradeName = "v052-to-v054" // must match UpgradeName in simapp/upgrades.go + upgradeName = "v052-to-v2" // must match UpgradeName in simapp/upgrades.go ) systest.Sut.StartChain(t, fmt.Sprintf("--comet.halt-height=%d", upgradeHeight+1)) diff --git a/x/upgrade/CHANGELOG.md b/x/upgrade/CHANGELOG.md index 1886aedd8f67..4e0521d3443a 100644 --- a/x/upgrade/CHANGELOG.md +++ b/x/upgrade/CHANGELOG.md @@ -25,6 +25,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +### Bug Fixes +* (x/upgrade) [#23179](https://github.com/cosmos/cosmos-sdk/pull/23179) Register missing implementation for SoftwareUpgradeProposal to avoid no concrete type registered for type URL /cosmos.upgrade.v1beta1.SoftwareUpgradeProposal against interface *v1beta1.Content error. + ## [v0.2.0-rc.1](https://github.com/cosmos/cosmos-sdk/releases/tag/x/upgrade/v0.2.0-rc.1) - 2024-12-18 ### Improvements diff --git a/x/upgrade/go.mod b/x/upgrade/go.mod index 9396ea02c8d2..209c5545fd33 100644 --- a/x/upgrade/go.mod +++ b/x/upgrade/go.mod @@ -11,6 +11,7 @@ require ( cosmossdk.io/log v1.5.0 cosmossdk.io/store v1.10.0-rc.1 cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a + cosmossdk.io/x/tx v1.0.0 github.com/cometbft/cometbft v1.0.0 github.com/cometbft/cometbft/api v1.0.0 github.com/cosmos/cosmos-proto v1.0.0-beta.5 @@ -46,7 +47,6 @@ require ( cosmossdk.io/schema v1.0.0 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect - cosmossdk.io/x/tx v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect diff --git a/x/upgrade/types/codec.go b/x/upgrade/types/codec.go index 0ab589acf313..abfd8a85600b 100644 --- a/x/upgrade/types/codec.go +++ b/x/upgrade/types/codec.go @@ -3,6 +3,7 @@ package types import ( "cosmossdk.io/core/registry" coretransaction "cosmossdk.io/core/transaction" + "cosmossdk.io/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/codec/legacy" "github.com/cosmos/cosmos-sdk/types/msgservice" @@ -23,6 +24,9 @@ func RegisterInterfaces(registrar registry.InterfaceRegistrar) { &MsgSoftwareUpgrade{}, &MsgCancelUpgrade{}, ) - + registrar.RegisterImplementations( + (*v1beta1.Content)(nil), + &SoftwareUpgradeProposal{}, + ) msgservice.RegisterMsgServiceDesc(registrar, &_Msg_serviceDesc) } diff --git a/x/upgrade/types/codec_test.go b/x/upgrade/types/codec_test.go new file mode 100644 index 000000000000..27198d1d12bf --- /dev/null +++ b/x/upgrade/types/codec_test.go @@ -0,0 +1,33 @@ +package types + +import ( + "testing" + + proto "github.com/cosmos/gogoproto/proto" + gogoprotoany "github.com/cosmos/gogoproto/types/any" + "github.com/stretchr/testify/require" + + "cosmossdk.io/x/gov/types/v1beta1" + "cosmossdk.io/x/tx/signing" + + codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" + "github.com/cosmos/cosmos-sdk/codec/types" +) + +func TestInterfaceRegistrationOfContent(t *testing.T) { + opts := codectestutil.CodecOptions{} + registrar, err := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{ + ProtoFiles: proto.HybridResolver, + SigningOptions: signing.Options{ + AddressCodec: opts.GetAddressCodec(), + ValidatorAddressCodec: opts.GetValidatorCodec(), + }, + }) + require.NoError(t, err) + RegisterInterfaces(registrar) + val := &gogoprotoany.Any{ + TypeUrl: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + Value: []byte{}, + } + require.NoError(t, registrar.UnpackAny(val, new(v1beta1.Content))) +} diff --git a/x/upgrade/types/proposal.go b/x/upgrade/types/proposal.go new file mode 100644 index 000000000000..0df833c9f73f --- /dev/null +++ b/x/upgrade/types/proposal.go @@ -0,0 +1,21 @@ +package types + +import ( + "cosmossdk.io/x/gov/types" + "cosmossdk.io/x/gov/types/v1beta1" +) + +// GetTitle returns the proposal title +func (sp *SoftwareUpgradeProposal) GetTitle() string { return sp.Title } + +// GetDescription returns the proposal description +func (sp *SoftwareUpgradeProposal) GetDescription() string { return sp.Description } + +// ProposalRoute returns the proposal router key +func (sp *SoftwareUpgradeProposal) ProposalRoute() string { return types.RouterKey } + +// ProposalType is "Text" +func (sp *SoftwareUpgradeProposal) ProposalType() string { return v1beta1.ProposalTypeText } + +// ValidateBasic validates the content's title and description of the proposal +func (sp *SoftwareUpgradeProposal) ValidateBasic() error { return v1beta1.ValidateAbstract(sp) } From 76e75bb4edb549f71d10299d30257ea02120858d Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 14 Jan 2025 18:00:33 +0800 Subject: [PATCH 3/9] fix(server/v2/cometbft): align default response for filter cmd when handleQueryP2P (#23365) --- server/v2/cometbft/query.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/v2/cometbft/query.go b/server/v2/cometbft/query.go index 0bdb9e40f060..ac8e0927bd81 100644 --- a/server/v2/cometbft/query.go +++ b/server/v2/cometbft/query.go @@ -29,6 +29,7 @@ func (c *consensus[T]) handleQueryP2P(path []string) (*abci.QueryResponse, error return c.idPeerFilter(arg) } } + return &abci.QueryResponse{}, nil } return nil, errorsmod.Wrap(cometerrors.ErrUnknownRequest, "expected second parameter to be 'filter'") From ec744ec88a5f7f5573de0f0a380b3a3a22e0b6ab Mon Sep 17 00:00:00 2001 From: caseylove Date: Tue, 14 Jan 2025 18:19:37 +0800 Subject: [PATCH 4/9] fix(schema): fix `make lint-fix` reports error (#23374) --- schema/appdata/mux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schema/appdata/mux.go b/schema/appdata/mux.go index 81a4fa795db8..c7b60d631717 100644 --- a/schema/appdata/mux.go +++ b/schema/appdata/mux.go @@ -138,8 +138,8 @@ func ListenerMux(listeners ...Listener) Listener { } mux.onBatch = func(batch PacketBatch) error { - for _, listener := range listeners { - err := batch.apply(&listener) + for i := range listeners { + err := batch.apply(&listeners[i]) if err != nil { return err } From d2aa3c25be6d9bc1af18c8cd980daa13b78ac553 Mon Sep 17 00:00:00 2001 From: hidewrong Date: Tue, 14 Jan 2025 18:21:06 +0800 Subject: [PATCH 5/9] chore(store): use the built-in clear to clear the map (#23375) Signed-off-by: hidewrong --- store/cache/cache.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/store/cache/cache.go b/store/cache/cache.go index 748eae8c422b..787e34da20ea 100644 --- a/store/cache/cache.go +++ b/store/cache/cache.go @@ -84,9 +84,7 @@ func (cmgr *CommitKVStoreCacheManager) Reset() { // Clear the map. // Please note that we are purposefully using the map clearing idiom. // See https://github.com/cosmos/cosmos-sdk/issues/6681. - for key := range cmgr.caches { - delete(cmgr.caches, key) - } + clear(cmgr.caches) } // CacheWrap implements the CacheWrapper interface From 5fb5ddaa1ce3b1d7c209a276ff4241d2404328e4 Mon Sep 17 00:00:00 2001 From: luchenhan <168071714+luchenhan@users.noreply.github.com> Date: Tue, 14 Jan 2025 20:56:31 +0900 Subject: [PATCH 6/9] docs: fix function name and comment (#23372) Signed-off-by: luchenhan --- baseapp/abci_test.go | 2 +- client/v2/tx/encoder.go | 2 +- crypto/ledger/ledger_secp256k1.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 7716b01421ce..32e3b94e3ff6 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -2204,7 +2204,7 @@ func TestABCI_ProcessProposal_PanicRecovery(t *testing.T) { }) } -// TestABCI_Proposal_Reset_State ensures that state is reset between runs of +// TestABCI_Proposal_Reset_State_Between_Calls ensures that state is reset between runs of // PrepareProposal and ProcessProposal in case they are called multiple times. // This is only valid for heights > 1, given that on height 1 we always set the // state to be deliverState. diff --git a/client/v2/tx/encoder.go b/client/v2/tx/encoder.go index 09011c8315e4..d1d9abae192b 100644 --- a/client/v2/tx/encoder.go +++ b/client/v2/tx/encoder.go @@ -115,7 +115,7 @@ func encodeTextTx(tx Tx) ([]byte, error) { return textMarshalOptions.Marshal(wTx.Tx) } -// decodeJsonTx decodes transaction bytes into an apitx.Tx structure using JSON format. +// decodeTextTx decodes transaction bytes into an apitx.Tx structure using TEXT format. func decodeTextTx(cdc codec.BinaryCodec, decoder Decoder) txDecoder { return func(txBytes []byte) (Tx, error) { jsonTx := new(txv1beta1.Tx) diff --git a/crypto/ledger/ledger_secp256k1.go b/crypto/ledger/ledger_secp256k1.go index 3449d0bfd1b1..ac152162b1c8 100644 --- a/crypto/ledger/ledger_secp256k1.go +++ b/crypto/ledger/ledger_secp256k1.go @@ -332,7 +332,7 @@ func getPubKeyUnsafe(device SECP256K1, path hd.BIP44Params) (types.PubKey, error return options.createPubkey(compressedPublicKey), nil } -// getPubKeyAddr reads the pubkey and the address from a ledger device. +// getPubKeyAddrSafe reads the pubkey and the address from a ledger device. // This function is marked as Safe as it will require user confirmation and // account and index will be shown in the device. // From dfb5cc29f2f853dff8e38cae0ee7c7995a463b75 Mon Sep 17 00:00:00 2001 From: caseylove Date: Tue, 14 Jan 2025 22:33:52 +0800 Subject: [PATCH 7/9] chore(store): use the built-in `clear` to clear the map (#23381) Co-authored-by: Alex | Interchain Labs --- store/cachekv/store.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/store/cachekv/store.go b/store/cachekv/store.go index 3509cef6aee3..33e39cb82fc1 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -104,12 +104,8 @@ func (store *Store) resetCaches() { // Clear the cache using the map clearing idiom // and not allocating fresh objects. // Please see https://bencher.orijtech.com/perfclinic/mapclearing/ - for key := range store.cache { - delete(store.cache, key) - } - for key := range store.unsortedCache { - delete(store.unsortedCache, key) - } + clear(store.cache) + clear(store.unsortedCache) } store.sortedCache = internal.NewBTree() } @@ -369,9 +365,7 @@ func (store *Store) dirtyItems(start, end []byte) { func (store *Store) clearUnsortedCacheSubset(unsorted []*kv.Pair, sortState sortState) { //nolint:staticcheck // We are in store v1. n := len(store.unsortedCache) if len(unsorted) == n { // This pattern allows the Go compiler to emit the map clearing idiom for the entire map. - for key := range store.unsortedCache { - delete(store.unsortedCache, key) - } + clear(store.unsortedCache) } else { // Otherwise, normally delete the unsorted keys from the map. for _, kv := range unsorted { delete(store.unsortedCache, conv.UnsafeBytesToStr(kv.Key)) From 80552a69c40e093877d06074a0de2166f4b78171 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 14 Jan 2025 15:45:45 +0100 Subject: [PATCH 8/9] docs(depinject): clarify how to wrap module (#23373) Co-authored-by: Alex | Interchain Labs --- depinject/appconfig/module.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/depinject/appconfig/module.go b/depinject/appconfig/module.go index 666a4739f97d..ce6f93337ed0 100644 --- a/depinject/appconfig/module.go +++ b/depinject/appconfig/module.go @@ -17,6 +17,10 @@ var Register = RegisterModule // will be injected into the container and can be requested by a provider // function. All module initialization should be handled by the provided options. // +// In some cases, a module may need to be manually overwritten from the global module +// registry. This can be done by calling RegisterModule again with the same config, +// but different options. This is useful when wrapping or overriding default modules. +// // Protobuf message types used for module configuration should define the // cosmos.app.v1alpha.module option and must explicitly specify go_package // to make debugging easier for users. From 64e828099c765b04d1a9deab3d91e3221f3652d2 Mon Sep 17 00:00:00 2001 From: fudancoder <171416994+fudancoder@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:45:55 +0800 Subject: [PATCH 9/9] refactor: use slices.Equal to simplify code (#23384) Signed-off-by: fudancoder --- core/header/service_test.go | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/core/header/service_test.go b/core/header/service_test.go index 7ac590a9fc7f..552165b1f135 100644 --- a/core/header/service_test.go +++ b/core/header/service_test.go @@ -2,6 +2,7 @@ package header import ( "crypto/sha256" + "slices" "testing" "time" ) @@ -29,7 +30,7 @@ func TestInfo_Bytes(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - if !bytesEqual(expectedBytes, bytes) { + if !slices.Equal(expectedBytes, bytes) { t.Errorf("expected bytes %v, got %v", expectedBytes, bytes) } } @@ -54,28 +55,16 @@ func TestInfo_FromBytes(t *testing.T) { if info.Height != 12345 { t.Errorf("expected Height %d, got %d", 12345, info.Height) } - if !bytesEqual([]byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.Hash) { + if !slices.Equal([]byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.Hash) { t.Errorf("expected Hash %v, got %v", []byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.Hash) } if info.Time != time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC) { t.Errorf("expected Time %v, got %v", time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC), info.Time) } - if !bytesEqual([]byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.AppHash) { + if !slices.Equal([]byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.AppHash) { t.Errorf("expected AppHash %v, got %v", []byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.AppHash) } if info.ChainID != "test-chain" { t.Errorf("expected ChainID %s, got %s", "test-chain", info.ChainID) } } - -func bytesEqual(a, b []byte) bool { - if len(a) != len(b) { - return false - } - for i := range a { - if a[i] != b[i] { - return false - } - } - return true -}