From d3eb83872ead6ef409bed6dafe4da1e76af5b48c Mon Sep 17 00:00:00 2001 From: Lucas Btd Date: Tue, 26 Jul 2022 10:05:42 +0200 Subject: [PATCH] feat(`network`): check no gentx are present in the initial genesis (#2646) * gentxs counter * gentx check * lint * fix errors * lint 2 * fix test --- ignite/pkg/cosmosutil/genesis.go | 10 +++++- ignite/pkg/cosmosutil/genesis_test.go | 35 ++++++++++++++++++++ ignite/services/network/networkchain/init.go | 24 ++++++++++++-- ignite/services/network/publish_test.go | 2 +- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/ignite/pkg/cosmosutil/genesis.go b/ignite/pkg/cosmosutil/genesis.go index 20c88bf54a..9a35f1fce0 100644 --- a/ignite/pkg/cosmosutil/genesis.go +++ b/ignite/pkg/cosmosutil/genesis.go @@ -50,6 +50,9 @@ type ( BondDenom string `json:"bond_denom"` } `json:"params"` } `json:"staking"` + Genutil struct { + GenTxs []struct{} `json:"gen_txs"` + } `json:"genutil"` } `json:"app_state"` } @@ -59,7 +62,7 @@ type ( GenesisField func(fields) ) -// HasAccount check if account exist into the genesis account +// HasAccount checks if account exist into the genesis account func (g Genesis) HasAccount(address string) bool { for _, account := range g.Accounts { if account == address { @@ -69,6 +72,11 @@ func (g Genesis) HasAccount(address string) bool { return false } +// GenTxCount returns the number of gentxs inside the genesis +func (cg ChainGenesis) GenTxCount() int { + return len(cg.AppState.Genutil.GenTxs) +} + // WithKeyValue sets key and value field to genesis file func WithKeyValue(key, value string) GenesisField { return func(f fields) { diff --git a/ignite/pkg/cosmosutil/genesis_test.go b/ignite/pkg/cosmosutil/genesis_test.go index a9e3afcd38..b080cc9ef5 100644 --- a/ignite/pkg/cosmosutil/genesis_test.go +++ b/ignite/pkg/cosmosutil/genesis_test.go @@ -58,12 +58,14 @@ func TestParseChainGenesis(t *testing.T) { Address string `json:"address"` }{{Address: "cosmos1dd246yq6z5vzjz9gh8cff46pll75yyl8ygndsj"}} genesis1.AppState.Staking.Params.BondDenom = "stake" + genesis1.AppState.Genutil.GenTxs = []struct{}{{}} // 1 gentx genesis2 := cosmosutil.ChainGenesis{ChainID: "earth-1"} genesis2.AppState.Auth.Accounts = []struct { Address string `json:"address"` }{{Address: "cosmos1mmlqwyqk7neqegffp99q86eckpm4pjah3ytlpa"}} genesis2.AppState.Staking.Params.BondDenom = "stake" + genesis2.AppState.Genutil.GenTxs = []struct{}{{}} // 1 gentx tests := []struct { name string @@ -339,3 +341,36 @@ func TestUpdateGenesis(t *testing.T) { }) } } + +func TestChainGenesis_GenTxCount(t *testing.T) { + // create a genesis with 10 gentx + testChainGenesis := cosmosutil.ChainGenesis{} + for i := 0; i < 10; i++ { + testChainGenesis.AppState.Genutil.GenTxs = append( + testChainGenesis.AppState.Genutil.GenTxs, + struct{}{}, + ) + } + + tests := []struct { + name string + chainGenesis cosmosutil.ChainGenesis + expected int + }{ + { + name: "should return 0 for initialized chain genesis", + chainGenesis: cosmosutil.ChainGenesis{}, + expected: 0, + }, + { + name: "should return the number of gentxs", + chainGenesis: testChainGenesis, + expected: 10, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.EqualValues(t, tt.expected, tt.chainGenesis.GenTxCount()) + }) + } +} diff --git a/ignite/services/network/networkchain/init.go b/ignite/services/network/networkchain/init.go index e389cca94c..5f3c207c5c 100644 --- a/ignite/services/network/networkchain/init.go +++ b/ignite/services/network/networkchain/init.go @@ -2,6 +2,7 @@ package networkchain import ( "context" + "errors" "fmt" "os" @@ -94,8 +95,8 @@ func (c *Chain) initGenesis(ctx context.Context) error { } - // check the genesis is valid - if err := c.checkGenesis(ctx); err != nil { + // check the initial genesis is valid + if err := c.checkInitialGenesis(ctx); err != nil { return err } @@ -104,13 +105,30 @@ func (c *Chain) initGenesis(ctx context.Context) error { } // checkGenesis checks the stored genesis is valid -func (c *Chain) checkGenesis(ctx context.Context) error { +func (c *Chain) checkInitialGenesis(ctx context.Context) error { // perform static analysis of the chain with the validate-genesis command. chainCmd, err := c.chain.Commands(ctx) if err != nil { return err } + // the chain initial genesis should not contain gentx, gentxs should be added through requests + genesisPath, err := c.chain.GenesisPath() + if err != nil { + return err + } + genesisFile, err := os.ReadFile(genesisPath) + if err != nil { + return err + } + chainGenesis, err := cosmosutil.ParseChainGenesis(genesisFile) + if err != nil { + return err + } + if chainGenesis.GenTxCount() > 0 { + return errors.New("the initial genesis for the chain should not contain gentx") + } + return chainCmd.ValidateGenesis(ctx) // TODO: static analysis of the genesis with validate-genesis doesn't check the full validity of the genesis diff --git a/ignite/services/network/publish_test.go b/ignite/services/network/publish_test.go index bf506c4f04..ac77467716 100644 --- a/ignite/services/network/publish_test.go +++ b/ignite/services/network/publish_test.go @@ -247,7 +247,7 @@ func TestPublish(t *testing.T) { var ( account = testutil.NewTestAccount(t, testutil.TestAccountName) customGenesisChainID = "test-custom-1" - customGenesisHash = "72a80a32e33513cd74423354502cef035e96b0bff59c754646b453b201d12d07" + customGenesisHash = "61da86775013bd18d6a019b533eedf1304b778fe8005090a0a0223720adfd8eb" gts = startGenesisTestServer(cosmosutil.ChainGenesis{ChainID: customGenesisChainID}) suite, network = newSuite(account) )