From e292bdab1080e13e26295950942fd0ef286db971 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:22:30 +0200 Subject: [PATCH] chore(simapp): audit (backport #16914) (#16922) Co-authored-by: Julien Robert --- simapp/app.go | 30 ---- simapp/internal/testnet/cometrpc_test.go | 169 ------------------ simapp/internal/testnet/cometstarter_test.go | 136 -------------- simapp/internal/testnet/doc.go | 10 -- simapp/internal/testnet/example_basic_test.go | 114 ------------ simapp/upgrades.go | 7 +- 6 files changed, 6 insertions(+), 460 deletions(-) delete mode 100644 simapp/internal/testnet/cometrpc_test.go delete mode 100644 simapp/internal/testnet/cometstarter_test.go delete mode 100644 simapp/internal/testnet/doc.go delete mode 100644 simapp/internal/testnet/example_basic_test.go diff --git a/simapp/app.go b/simapp/app.go index fc837aa1c29f..2754dc24adde 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -130,36 +130,6 @@ var ( _ servertypes.Application = (*SimApp)(nil) ) -// stdAccAddressCodec is a temporary address codec that we will use until we -// can populate it with the correct bech32 prefixes without depending on the global. -type stdAccAddressCodec struct{} - -func (g stdAccAddressCodec) StringToBytes(text string) ([]byte, error) { - if text == "" { - return nil, nil - } - return sdk.AccAddressFromBech32(text) -} - -func (g stdAccAddressCodec) BytesToString(bz []byte) (string, error) { - if bz == nil { - return "", nil - } - return sdk.AccAddress(bz).String(), nil -} - -// stdValAddressCodec is a temporary address codec that we will use until we -// can populate it with the correct bech32 prefixes without depending on the global. -type stdValAddressCodec struct{} - -func (g stdValAddressCodec) StringToBytes(text string) ([]byte, error) { - return sdk.ValAddressFromBech32(text) -} - -func (g stdValAddressCodec) BytesToString(bz []byte) (string, error) { - return sdk.ValAddress(bz).String(), nil -} - // SimApp extends an ABCI application, but with most of its parameters exported. // They are exported for convenience in creating helper functions, as object // capabilities aren't needed for testing. diff --git a/simapp/internal/testnet/cometrpc_test.go b/simapp/internal/testnet/cometrpc_test.go deleted file mode 100644 index c291a0dc7ff4..000000000000 --- a/simapp/internal/testnet/cometrpc_test.go +++ /dev/null @@ -1,169 +0,0 @@ -package testnet_test - -import ( - "context" - "testing" - "time" - - cmtcfg "github.com/cometbft/cometbft/config" - "github.com/cometbft/cometbft/rpc/client/http" - dbm "github.com/cosmos/cosmos-db" - "github.com/stretchr/testify/require" - - "cosmossdk.io/log" - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - "github.com/cosmos/cosmos-sdk/testutil/testnet" - sdk "github.com/cosmos/cosmos-sdk/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -const memdb = "memdb" - -// A single comet server in a network runs an RPC server successfully. -func TestCometRPC_SingleRPCServer(t *testing.T) { - const nVals = 2 - - valPKs := testnet.NewValidatorPrivKeys(nVals) - cmtVals := valPKs.CometGenesisValidators() - stakingVals := cmtVals.StakingValidators() - - const chainID = "comet-rpc-singleton" - - b := testnet.DefaultGenesisBuilderOnlyValidators( - chainID, - stakingVals, - sdk.NewCoin(sdk.DefaultBondDenom, sdk.DefaultPowerReduction), - ) - - jGenesis := b.Encode() - - // Logs shouldn't be necessary here because we are exercising CometStarter, - // and only doing a very basic check that the RPC talks to the app. - logger := log.NewNopLogger() - - nodes, err := testnet.NewNetwork(nVals, func(idx int) *testnet.CometStarter { - rootDir := t.TempDir() - - app := simapp.NewSimApp( - logger, - dbm.NewMemDB(), - nil, - true, - simtestutil.NewAppOptionsWithFlagHome(rootDir), - baseapp.SetChainID(chainID), - ) - - cfg := cmtcfg.DefaultConfig() - cfg.BaseConfig.DBBackend = memdb - - cs := testnet.NewCometStarter( - app, - cfg, - valPKs[idx].Val, - jGenesis, - rootDir, - ) - - // Only enable the RPC on the first service. - if idx == 0 { - cs = cs.RPCListen() - } - - return cs - }) - defer nodes.StopAndWait() - require.NoError(t, err) - - // Once HTTP client to be shared across the following subtests. - c, err := http.New(nodes[0].Config().RPC.ListenAddress, "/websocket") - require.NoError(t, err) - - t.Run("status query", func(t *testing.T) { - ctx := context.Background() - st, err := c.Status(ctx) - require.NoError(t, err) - - // Simple assertion to ensure we have a functioning RPC. - require.Equal(t, chainID, st.NodeInfo.Network) - }) - - // Block until reported height is at least 1, - // otherwise we can't make transactions. - require.NoError(t, testnet.WaitForNodeHeight(nodes[0], 1, 10*time.Second)) - - t.Run("simple abci query", func(t *testing.T) { - res, err := c.ABCIQuery( - context.Background(), - "/cosmos.bank.v1beta1.Query/TotalSupply", - nil, - ) - require.NoError(t, err) - - registry := codectypes.NewInterfaceRegistry() - cdc := codec.NewProtoCodec(registry) - - var tsResp banktypes.QueryTotalSupplyResponse - require.NoError(t, cdc.Unmarshal(res.Response.Value, &tsResp)) - - // Just check that something is reported in the supply. - require.NotEmpty(t, tsResp.Supply) - }) -} - -// Starting two comet instances with an RPC server, -// fails with a predictable error. -func TestCometRPC_MultipleRPCError(t *testing.T) { - const nVals = 2 - - valPKs := testnet.NewValidatorPrivKeys(nVals) - cmtVals := valPKs.CometGenesisValidators() - stakingVals := cmtVals.StakingValidators() - - const chainID = "comet-rpc-multiple" - - b := testnet.DefaultGenesisBuilderOnlyValidators( - chainID, - stakingVals, - sdk.NewCoin(sdk.DefaultBondDenom, sdk.DefaultPowerReduction), - ) - - jGenesis := b.Encode() - - // Logs shouldn't be necessary here because we are exercising CometStarter. - logger := log.NewNopLogger() - - nodes, err := testnet.NewNetwork(nVals, func(idx int) *testnet.CometStarter { - rootDir := t.TempDir() - - app := simapp.NewSimApp( - logger, - dbm.NewMemDB(), - nil, - true, - simtestutil.NewAppOptionsWithFlagHome(rootDir), - baseapp.SetChainID(chainID), - ) - - cfg := cmtcfg.DefaultConfig() - cfg.BaseConfig.DBBackend = memdb - - return testnet.NewCometStarter( - app, - cfg, - valPKs[idx].Val, - jGenesis, - rootDir, - ).RPCListen() // Every node has RPCListen enabled, which will cause a failure. - }) - defer nodes.StopAndWait() - - // Returned error is convertible to CometRPCInUseError. - // We can't test the exact value because it includes a stack trace. - require.Error(t, err) - require.ErrorAs(t, err, new(testnet.CometRPCInUseError)) -} diff --git a/simapp/internal/testnet/cometstarter_test.go b/simapp/internal/testnet/cometstarter_test.go deleted file mode 100644 index 7bb814aa90bc..000000000000 --- a/simapp/internal/testnet/cometstarter_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package testnet_test - -import ( - "fmt" - "math/rand" - "net" - "testing" - "time" - - cmtcfg "github.com/cometbft/cometbft/config" - dbm "github.com/cosmos/cosmos-db" - "github.com/stretchr/testify/require" - - "cosmossdk.io/log" - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/baseapp" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - "github.com/cosmos/cosmos-sdk/testutil/testnet" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// Use a limited set of available ports to ensure that -// retries eventually land on a free port. -func TestCometStarter_PortContention(t *testing.T) { - if testing.Short() { - t.Skip("skipping long test in short mode") - } - - const nVals = 4 - - // Find n+1 addresses that should be free. - // Ephemeral port range should start at about 49k+ - // according to `sysctl net.inet.ip.portrange` on macOS, - // and at about 32k+ on Linux - // according to `sysctl net.ipv4.ip_local_port_range`. - // - // Because we attempt to find free addresses outside that range, - // it is unlikely that another process will claim a port - // we discover to be free, during the time this test runs. - const portSeekStart = 19000 - reuseAddrs := make([]string, 0, nVals+1) - for i := portSeekStart; i < portSeekStart+1000; i++ { - addr := fmt.Sprintf("127.0.0.1:%d", i) - ln, err := net.Listen("tcp", addr) - if err != nil { - // No need to log the failure. - continue - } - - // If the port was free, append it to our reusable addresses. - reuseAddrs = append(reuseAddrs, "tcp://"+addr) - _ = ln.Close() - - if len(reuseAddrs) == nVals+1 { - break - } - } - - if len(reuseAddrs) != nVals+1 { - t.Fatalf("needed %d free ports but only found %d", nVals+1, len(reuseAddrs)) - } - - // Now that we have one more port than the number of validators, - // there is a good chance that picking a random port will conflict with a previously chosen one. - // But since CometStarter retries several times, - // it should eventually land on a free port. - - valPKs := testnet.NewValidatorPrivKeys(nVals) - cmtVals := valPKs.CometGenesisValidators() - stakingVals := cmtVals.StakingValidators() - - const chainID = "simapp-cometstarter" - - b := testnet.DefaultGenesisBuilderOnlyValidators( - chainID, - stakingVals, - sdk.NewCoin(sdk.DefaultBondDenom, sdk.DefaultPowerReduction), - ) - - jGenesis := b.Encode() - - // Use an info-level logger, because the debug logs in comet are noisy - // and there is a data race in comet debug logs, - // due to be fixed in v0.37.1 which is not yet released: - // https://github.com/cometbft/cometbft/pull/532 - logger := log.NewTestLoggerInfo(t) - - const nRuns = 4 - for i := 0; i < nRuns; i++ { - t.Run(fmt.Sprintf("attempt %d", i), func(t *testing.T) { - nodes, err := testnet.NewNetwork(nVals, func(idx int) *testnet.CometStarter { - rootDir := t.TempDir() - - app := simapp.NewSimApp( - logger.With("instance", idx), - dbm.NewMemDB(), - nil, - true, - simtestutil.NewAppOptionsWithFlagHome(rootDir), - baseapp.SetChainID(chainID), - ) - - cfg := cmtcfg.DefaultConfig() - - // memdb is sufficient for this test. - cfg.BaseConfig.DBBackend = "memdb" - - return testnet.NewCometStarter( - app, - cfg, - valPKs[idx].Val, - jGenesis, - rootDir, - ). - Logger(logger.With("rootmodule", fmt.Sprintf("comet_node-%d", idx))). - TCPAddrChooser(func() string { - // This chooser function is the key of this test, - // where there is only one more available address than there are nodes. - // Therefore it is likely that an address will already be in use, - // thereby exercising the address-in-use retry. - return reuseAddrs[rand.Intn(len(reuseAddrs))] - }) - }) - - // Ensure nodes are stopped completely, - // so that we don't get t.Cleanup errors around directories not being empty. - defer nodes.StopAndWait() - require.NoError(t, err) - - // Ensure that the height advances. - // Looking for height 2 seems more meaningful than 1. - require.NoError(t, testnet.WaitForNodeHeight(nodes[0], 2, 10*time.Second)) - }) - } -} diff --git a/simapp/internal/testnet/doc.go b/simapp/internal/testnet/doc.go deleted file mode 100644 index 19064ddd0f45..000000000000 --- a/simapp/internal/testnet/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package testnet contains tests for -// [github.com/cosmos/cosmos-sdk/testutil/testnet]. -// -// Eventually all of these tests will move into that package, -// but that is currently blocked on having a minimal app defined -// in the root cosmos-sdk Go module. -// Once that app is available, the contents of this package -// will be moved to testutil/testnet, -// and references to SimApp will be replaced by the minimal app. -package testnet diff --git a/simapp/internal/testnet/example_basic_test.go b/simapp/internal/testnet/example_basic_test.go deleted file mode 100644 index 4cf603b6c328..000000000000 --- a/simapp/internal/testnet/example_basic_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package testnet_test - -import ( - "fmt" - "os" - "path/filepath" - - cmtcfg "github.com/cometbft/cometbft/config" - dbm "github.com/cosmos/cosmos-db" - - "cosmossdk.io/log" - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/baseapp" - simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - "github.com/cosmos/cosmos-sdk/testutil/testnet" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func Example_basicUsage() { - const nVals = 2 - - // Set up new private keys for the set of validators. - valPKs := testnet.NewValidatorPrivKeys(nVals) - - // Comet-style validators. - cmtVals := valPKs.CometGenesisValidators() - - // Cosmos SDK staking validators for genesis. - stakingVals := cmtVals.StakingValidators() - - const chainID = "example-basic" - - // Create a genesis builder that only requires validators, - // without any separate delegator accounts. - // - // If you need further customization, start with testnet.NewGenesisBuilder(). - b := testnet.DefaultGenesisBuilderOnlyValidators( - chainID, - stakingVals, - // The amount to use in each validator's account during gentx. - sdk.NewCoin(sdk.DefaultBondDenom, sdk.DefaultPowerReduction), - ) - - // JSON-formatted genesis. - jGenesis := b.Encode() - - // In this example, we have an outer root directory for the validators. - // Use t.TempDir() in tests. - rootDir, err := os.MkdirTemp("", "testnet-example-") - if err != nil { - panic(err) - } - defer os.RemoveAll(rootDir) - - // In tests, you probably want to use log.NewTestLoggerInfo(t). - logger := log.NewNopLogger() - - // The NewNetwork function creates a network of validators. - // We have to provide a callback to return CometStarter instances. - // NewNetwork will start all the comet instances concurrently - // and join the nodes together. - nodes, err := testnet.NewNetwork(nVals, func(idx int) *testnet.CometStarter { - // Make a new directory for the validator being created. - // In tests, this would be a simpler call to t.TempDir(). - dir := filepath.Join(rootDir, fmt.Sprintf("val-%d", idx)) - if err := os.Mkdir(dir, 0o755); err != nil { - panic(err) - } - - // TODO: use a different minimal app for this. - app := simapp.NewSimApp( - logger.With("instance", idx), - dbm.NewMemDB(), - nil, - true, - simtestutil.NewAppOptionsWithFlagHome(rootDir), - baseapp.SetChainID(chainID), - ) - - // Each CometStarter instance must be associated with - // a distinct comet Config object, - // as the CometStarter will automatically modify some fields, - // including P2P.ListenAddress. - cfg := cmtcfg.DefaultConfig() - - // No need to persist comet's DB to disk in this example. - cfg.BaseConfig.DBBackend = "memdb" - - return testnet.NewCometStarter( - app, - cfg, - valPKs[idx].Val, // Validator private key for this comet instance. - jGenesis, // Raw bytes of genesis file. - dir, // Where to put files on disk. - ).Logger(logger.With("root_module", fmt.Sprintf("comet_%d", idx))) - }) - // StopAndWait must be deferred before the error check, - // as the nodes value may contain some successfully started instances. - defer nodes.StopAndWait() - if err != nil { - panic(err) - } - - // Now you can begin interacting with the nodes. - // For the sake of this example, we'll just check - // a couple simple properties of one node. - fmt.Println(nodes[0].IsListening()) - fmt.Println(nodes[0].GenesisDoc().ChainID) - - // Output: - // true - // example-basic -} diff --git a/simapp/upgrades.go b/simapp/upgrades.go index d59e78108d72..66c9fb87e7c0 100644 --- a/simapp/upgrades.go +++ b/simapp/upgrades.go @@ -4,6 +4,7 @@ import ( "context" storetypes "cosmossdk.io/store/types" + circuittypes "cosmossdk.io/x/circuit/types" upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -31,7 +32,11 @@ func (app SimApp) RegisterUpgradeHandlers() { } if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := storetypes.StoreUpgrades{} + storeUpgrades := storetypes.StoreUpgrades{ + Added: []string{ + circuittypes.ModuleName, + }, + } // configure store loader that checks if version == upgradeHeight and applies store upgrades app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))