From 8426c5f5a368d3e545cfede2f19353fc9e72f1a9 Mon Sep 17 00:00:00 2001 From: evan-forbes Date: Wed, 16 Nov 2022 18:19:17 -0600 Subject: [PATCH 1/4] chore!: refactor the testnode to expose the genesis state and have a default network --- testutil/testnode/full_node.go | 90 ++++++++++++++++++++++++----- testutil/testnode/full_node_test.go | 5 +- testutil/testnode/node_init.go | 21 ------- 3 files changed, 81 insertions(+), 35 deletions(-) diff --git a/testutil/testnode/full_node.go b/testutil/testnode/full_node.go index a19189f1a4..89d4c0ef2b 100644 --- a/testutil/testnode/full_node.go +++ b/testutil/testnode/full_node.go @@ -1,6 +1,7 @@ package testnode import ( + "encoding/json" "os" "testing" "time" @@ -8,11 +9,14 @@ import ( "github.com/celestiaorg/celestia-app/app" "github.com/celestiaorg/celestia-app/app/encoding" "github.com/celestiaorg/celestia-app/cmd/celestia-appd/cmd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types" "github.com/cosmos/cosmos-sdk/server" srvtypes "github.com/cosmos/cosmos-sdk/server/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/genutil" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -26,12 +30,18 @@ import ( ) // New creates a ready to use tendermint node that operates a single validator -// celestia-app network. The passed account names in fundedAccounts are used to -// generate new private keys, which are included as funded accounts in the -// genesis file. These keys are stored in the keyring that is returned in the -// client.Context. NOTE: the forced delay between blocks, TimeIotaMs in the -// consensus parameters, is set to the lowest possible value (1ms). -func New(t *testing.T, cparams *tmproto.ConsensusParams, tmCfg *config.Config, supressLog bool, fundedAccounts ...string) (*node.Node, srvtypes.Application, Context, error) { +// celestia-app network using the provided genesis state. The provided keyring +// is stored in the client.Context that is returned. +// +// NOTE: the forced delay between blocks, TimeIotaMs in the consensus +// parameters, is set to the lowest possible value (1ms). +func New( + t *testing.T, + cparams *tmproto.ConsensusParams, + tmCfg *config.Config, + supressLog bool, + genState map[string]json.RawMessage, + kr keyring.Keyring) (*node.Node, srvtypes.Application, Context, error) { var logger log.Logger if supressLog { logger = log.NewNopLogger() @@ -49,12 +59,6 @@ func New(t *testing.T, cparams *tmproto.ConsensusParams, tmCfg *config.Config, s encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) - genState := app.ModuleBasics.DefaultGenesis(encCfg.Codec) - - fundedAccounts = append(fundedAccounts, "validator") - - kr, bankBals, authAccs := fundKeyringAccounts(encCfg.Codec, fundedAccounts...) - nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile()) if err != nil { return nil, nil, Context{}, err @@ -70,7 +74,7 @@ func New(t *testing.T, cparams *tmproto.ConsensusParams, tmCfg *config.Config, s return nil, nil, Context{}, err } - err = initGenFiles(cparams, genState, encCfg.Codec, authAccs, bankBals, tmCfg.GenesisFile(), chainID) + err = initGenFiles(cparams, genState, encCfg.Codec, tmCfg.GenesisFile(), chainID) if err != nil { return nil, nil, Context{}, err } @@ -135,3 +139,63 @@ func DefaultTendermintConfig() *config.Config { tmCfg.Mempool.MaxTxBytes = 22020096 // 21MB return tmCfg } + +// DefaultGenesisState will create +func DefaultGenesisState(fundedAccounts ...string) (map[string]json.RawMessage, keyring.Keyring, error) { + encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) + state := app.ModuleBasics.DefaultGenesis(encCfg.Codec) + fundedAccounts = append(fundedAccounts, "validator") + kr, bankBals, authAccs := fundKeyringAccounts(encCfg.Codec, fundedAccounts...) + + // set the accounts in the genesis state + var authGenState authtypes.GenesisState + encCfg.Codec.MustUnmarshalJSON(state[authtypes.ModuleName], &authGenState) + + accounts, err := authtypes.PackAccounts(authAccs) + if err != nil { + return nil, nil, err + } + + authGenState.Accounts = append(authGenState.Accounts, accounts...) + state[authtypes.ModuleName] = encCfg.Codec.MustMarshalJSON(&authGenState) + + // set the balances in the genesis state + var bankGenState banktypes.GenesisState + encCfg.Codec.MustUnmarshalJSON(state[banktypes.ModuleName], &bankGenState) + + bankGenState.Balances = append(bankGenState.Balances, bankBals...) + state[banktypes.ModuleName] = encCfg.Codec.MustMarshalJSON(&bankGenState) + + return state, kr, nil +} + +// DefaultNetwork creates an in-process single validator celestia-app network +// using test friendly defaults. These defaults include fast block times and +// funded accounts. The returned client.Context has a keyring with all of the +// funded keys stored in it. +func DefaultNetwork(t *testing.T, blockTime time.Duration) (cleanup func(), accounts []string, cctx Context) { + // we create an arbitrary number of funded accounts + for i := 0; i < 300; i++ { + accounts = append(accounts, tmrand.Str(9)) + } + + tmCfg := DefaultTendermintConfig() + tmCfg.Consensus.TimeoutCommit = blockTime + + genState, kr, err := DefaultGenesisState(accounts...) + require.NoError(t, err) + + tmNode, app, cctx, err := New(t, DefaultParams(), tmCfg, false, genState, kr) + require.NoError(t, err) + + cctx, stopNode, err := StartNode(tmNode, cctx) + require.NoError(t, err) + + cctx, cleanupGRPC, err := StartGRPCServer(app, DefaultAppConfig(), cctx) + require.NoError(t, err) + + return func() { + stopNode() + cleanupGRPC() + }, accounts, cctx +} diff --git a/testutil/testnode/full_node_test.go b/testutil/testnode/full_node_test.go index 9bc17aa45c..f99af14b08 100644 --- a/testutil/testnode/full_node_test.go +++ b/testutil/testnode/full_node_test.go @@ -36,7 +36,10 @@ func (s *IntegrationTestSuite) SetupSuite() { s.accounts = append(s.accounts, tmrand.Str(9)) } - tmNode, app, cctx, err := New(s.T(), DefaultParams(), DefaultTendermintConfig(), false, s.accounts...) + genState, kr, err := DefaultGenesisState(s.accounts...) + require.NoError(err) + + tmNode, app, cctx, err := New(s.T(), DefaultParams(), DefaultTendermintConfig(), false, genState, kr) require.NoError(err) cctx, stopNode, err := StartNode(tmNode, cctx) diff --git a/testutil/testnode/node_init.go b/testutil/testnode/node_init.go index 921483eaaa..c095803ee4 100644 --- a/testutil/testnode/node_init.go +++ b/testutil/testnode/node_init.go @@ -101,30 +101,9 @@ func initGenFiles( cparams *tmproto.ConsensusParams, state map[string]json.RawMessage, codec codec.Codec, - genAccounts []authtypes.GenesisAccount, - genBalances []banktypes.Balance, file, chainID string, ) error { - // set the accounts in the genesis state - var authGenState authtypes.GenesisState - codec.MustUnmarshalJSON(state[authtypes.ModuleName], &authGenState) - - accounts, err := authtypes.PackAccounts(genAccounts) - if err != nil { - return err - } - - authGenState.Accounts = append(authGenState.Accounts, accounts...) - state[authtypes.ModuleName] = codec.MustMarshalJSON(&authGenState) - - // set the balances in the genesis state - var bankGenState banktypes.GenesisState - codec.MustUnmarshalJSON(state[banktypes.ModuleName], &bankGenState) - - bankGenState.Balances = append(bankGenState.Balances, genBalances...) - state[banktypes.ModuleName] = codec.MustMarshalJSON(&bankGenState) - appGenStateJSON, err := json.MarshalIndent(state, "", " ") if err != nil { return err From 81730f8a1003b9ac5a57c78ab426a0e20c4ec6a0 Mon Sep 17 00:00:00 2001 From: evan-forbes Date: Thu, 17 Nov 2022 18:47:43 -0600 Subject: [PATCH 2/4] chore: gofumpt --- testutil/testnode/full_node.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testutil/testnode/full_node.go b/testutil/testnode/full_node.go index 89d4c0ef2b..afd181dbb2 100644 --- a/testutil/testnode/full_node.go +++ b/testutil/testnode/full_node.go @@ -41,7 +41,8 @@ func New( tmCfg *config.Config, supressLog bool, genState map[string]json.RawMessage, - kr keyring.Keyring) (*node.Node, srvtypes.Application, Context, error) { + kr keyring.Keyring, +) (*node.Node, srvtypes.Application, Context, error) { var logger log.Logger if supressLog { logger = log.NewNopLogger() From 02c81bda841c1c353d2611cf07a0a2ef4abfe114 Mon Sep 17 00:00:00 2001 From: evan-forbes Date: Thu, 17 Nov 2022 18:55:56 -0600 Subject: [PATCH 3/4] golf: predefine slice capacity --- testutil/testnode/full_node.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testutil/testnode/full_node.go b/testutil/testnode/full_node.go index afd181dbb2..74eec9ed33 100644 --- a/testutil/testnode/full_node.go +++ b/testutil/testnode/full_node.go @@ -176,8 +176,9 @@ func DefaultGenesisState(fundedAccounts ...string) (map[string]json.RawMessage, // funded keys stored in it. func DefaultNetwork(t *testing.T, blockTime time.Duration) (cleanup func(), accounts []string, cctx Context) { // we create an arbitrary number of funded accounts + accounts = make([]string, 300) for i := 0; i < 300; i++ { - accounts = append(accounts, tmrand.Str(9)) + accounts[i] = tmrand.Str(9) } tmCfg := DefaultTendermintConfig() From 2738659d704cffa18f5e50c75eaf1f7c27c67b7d Mon Sep 17 00:00:00 2001 From: Evan Forbes <42654277+evan-forbes@users.noreply.github.com> Date: Fri, 18 Nov 2022 08:18:39 -0600 Subject: [PATCH 4/4] chore: update docs Co-authored-by: Rootul P --- testutil/testnode/full_node.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testutil/testnode/full_node.go b/testutil/testnode/full_node.go index 74eec9ed33..bed9a9042a 100644 --- a/testutil/testnode/full_node.go +++ b/testutil/testnode/full_node.go @@ -141,7 +141,9 @@ func DefaultTendermintConfig() *config.Config { return tmCfg } -// DefaultGenesisState will create +// DefaultGenesisState returns a default genesis state and a keyring with +// accounts that have coins. The keyring accounts are based on the +// fundedAccounts parameter. func DefaultGenesisState(fundedAccounts ...string) (map[string]json.RawMessage, keyring.Keyring, error) { encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) state := app.ModuleBasics.DefaultGenesis(encCfg.Codec)