From 0c258428cad2b3a59958d088ce8a407b8ac6c763 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 17:08:55 -0300 Subject: [PATCH 01/36] chore: try to clean up all and only then return the error --- test/e2e/containers/containers.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index 09782d7f1..c1daa3597 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -321,17 +321,17 @@ func (m *Manager) RemoveNodeResource(containerName string) error { } // ClearResources removes all outstanding Docker resources created by the Manager. -func (m *Manager) ClearResources() error { +func (m *Manager) ClearResources() (e error) { for _, resource := range m.resources { if err := m.pool.Purge(resource); err != nil { - return err + e = err } } if err := m.pool.RemoveNetwork(m.network); err != nil { - return err + e = err } - return nil + return e } func noRestart(config *docker.HostConfig) { From 61278f067e3aaaa10d1c723050ccdbe7e9309471 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 17:13:53 -0300 Subject: [PATCH 02/36] chore: add errgroup to clear resources and new mount path to set proposasl --- test/e2e/configurer/base.go | 17 ++++++++++------- test/e2e/containers/containers.go | 19 ++++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/test/e2e/configurer/base.go b/test/e2e/configurer/base.go index 6744fff94..d7d474be1 100644 --- a/test/e2e/configurer/base.go +++ b/test/e2e/configurer/base.go @@ -19,6 +19,7 @@ import ( "github.com/babylonchain/babylon/types" types2 "github.com/babylonchain/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" ) // baseConfigurer is the base implementation for the @@ -39,16 +40,18 @@ const defaultSyncUntilHeight = 3 func (bc *baseConfigurer) ClearResources() error { bc.t.Log("tearing down e2e integration test suite...") - if err := bc.containerManager.ClearResources(); err != nil { - return err - } + g := new(errgroup.Group) + g.Go(func() error { + return bc.containerManager.ClearResources() + }) for _, chainConfig := range bc.chainConfigs { - if err := os.RemoveAll(chainConfig.DataDir); err != nil { - return err - } + chainConfig := chainConfig + g.Go(func() error { + return os.RemoveAll(chainConfig.DataDir) + }) } - return nil + return g.Wait() } func (bc *baseConfigurer) GetChainConfig(chainIndex int) *chain.Config { diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index c1daa3597..737af78ea 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -13,6 +13,7 @@ import ( "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" ) const ( @@ -264,6 +265,7 @@ func (m *Manager) RunNodeResource(chainId string, containerName, valCondifDir st Mounts: []string{ fmt.Sprintf("%s/:%s", valCondifDir, BabylonHomePath), fmt.Sprintf("%s/bytecode:/bytecode", pwd), + fmt.Sprintf("%s/upgrades:/upgrades", pwd), }, } @@ -322,16 +324,19 @@ func (m *Manager) RemoveNodeResource(containerName string) error { // ClearResources removes all outstanding Docker resources created by the Manager. func (m *Manager) ClearResources() (e error) { + g := new(errgroup.Group) for _, resource := range m.resources { - if err := m.pool.Purge(resource); err != nil { - e = err - } + resource := resource + g.Go(func() error { + return m.pool.Purge(resource) + }) } - if err := m.pool.RemoveNetwork(m.network); err != nil { - e = err - } - return e + g.Go(func() error { + return m.pool.RemoveNetwork(m.network) + }) + + return g.Wait() } func noRestart(config *docker.HostConfig) { From b1f9a76f711af35a8c2ccda05a02a68d2329ad73 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 17:15:10 -0300 Subject: [PATCH 03/36] chore: add upgrade e2e from current branch --- app/app.go | 7 +- app/upgrades/vanilla/upgrades.go | 1 - test/e2e/configurer/factory.go | 17 +++++ test/e2e/e2e_test.go | 5 ++ ...oftware_upgrade_current_branch_e2e_test.go | 70 +++++++++++++++++++ test/e2e/upgrades/vanilla.json | 14 ++++ 6 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 test/e2e/software_upgrade_current_branch_e2e_test.go create mode 100644 test/e2e/upgrades/vanilla.json diff --git a/app/app.go b/app/app.go index 67b0b7800..cd05f8084 100644 --- a/app/app.go +++ b/app/app.go @@ -94,6 +94,7 @@ import ( "github.com/spf13/cast" "github.com/babylonchain/babylon/app/upgrades" + "github.com/babylonchain/babylon/app/upgrades/vanilla" bbn "github.com/babylonchain/babylon/types" appkeepers "github.com/babylonchain/babylon/app/keepers" @@ -158,8 +159,10 @@ var ( } // software upgrades and forks - Upgrades = []upgrades.Upgrade{} - Forks = []upgrades.Fork{} + Upgrades = []upgrades.Upgrade{ + vanilla.Upgrade, + } + Forks = []upgrades.Fork{} ) func init() { diff --git a/app/upgrades/vanilla/upgrades.go b/app/upgrades/vanilla/upgrades.go index 1cc0c9060..156e5de72 100644 --- a/app/upgrades/vanilla/upgrades.go +++ b/app/upgrades/vanilla/upgrades.go @@ -32,7 +32,6 @@ func CreateUpgradeHandler( keepers *keepers.AppKeepers, ) upgradetypes.UpgradeHandler { return func(context context.Context, _plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - ctx := sdk.UnwrapSDKContext(context) propVanilla(ctx, &keepers.AccountKeeper, &keepers.BTCStakingKeeper) diff --git a/test/e2e/configurer/factory.go b/test/e2e/configurer/factory.go index bcac549e5..0182a40dc 100644 --- a/test/e2e/configurer/factory.go +++ b/test/e2e/configurer/factory.go @@ -195,3 +195,20 @@ func NewBTCStakingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, containerManager, ), nil } + +// NewSoftwareUpgradeTest returns a new Configurer for Software Upgrade testing +func NewSoftwareUpgradeTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { + containerManager, err := containers.NewManager(isDebugLogEnabled, false) + if err != nil { + return nil, err + } + + return NewCurrentBranchConfigurer(t, + []*chain.Config{ + // we only need 1 chain for testing upgrade + chain.New(t, containerManager, initialization.ChainAID, validatorConfigsChainA, nil), + }, + baseSetup, // base set up + containerManager, + ), nil +} diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 4c877c6c8..d27b66acf 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -35,3 +35,8 @@ func TestBTCTimestampingPhase2RlyTestSuite(t *testing.T) { func TestBTCStakingTestSuite(t *testing.T) { suite.Run(t, new(BTCStakingTestSuite)) } + +// TestSoftwareUpgradeTestSuite tests software upgrade protocol end-to-end +func TestSoftwareUpgradeTestSuite(t *testing.T) { + suite.Run(t, new(SoftwareUpgradeCurrentBranchTestSuite)) +} diff --git a/test/e2e/software_upgrade_current_branch_e2e_test.go b/test/e2e/software_upgrade_current_branch_e2e_test.go new file mode 100644 index 000000000..bb319a841 --- /dev/null +++ b/test/e2e/software_upgrade_current_branch_e2e_test.go @@ -0,0 +1,70 @@ +package e2e + +import ( + "github.com/stretchr/testify/suite" + + "github.com/babylonchain/babylon/test/e2e/configurer" +) + +var ( +// r = rand.New(rand.NewSource(time.Now().Unix())) +// net = &chaincfg.SimNetParams +// // finality provider +// fpBTCSK, _, _ = datagen.GenRandomBTCKeyPair(r) +// cacheFP *bstypes.FinalityProvider +// // BTC delegation +// delBTCSK, delBTCPK, _ = datagen.GenRandomBTCKeyPair(r) +// // covenant +// covenantSKs, _, covenantQuorum = bstypes.DefaultCovenantCommittee() + +// stakingValue = int64(2 * 10e8) +) + +const ( + // Mount path in container is fmt.Sprintf("%s/upgrades:/upgrades", pwd) + vanillaUpgradeFilePath = "/upgrades/vanilla.json" +) + +type SoftwareUpgradeCurrentBranchTestSuite struct { + suite.Suite + + configurer configurer.Configurer +} + +func (s *SoftwareUpgradeCurrentBranchTestSuite) SetupSuite() { + s.T().Log("setting up e2e integration test suite...") + var err error + + // The e2e test flow is as follows: + // + // 1. Configure 1 chain with some validator nodes + // 2. Execute various e2e tests + s.configurer, err = configurer.NewSoftwareUpgradeTest(s.T(), true) + s.NoError(err) + err = s.configurer.ConfigureChains() + s.NoError(err) + err = s.configurer.RunSetup() + s.NoError(err) +} + +func (s *SoftwareUpgradeCurrentBranchTestSuite) TearDownSuite() { + err := s.configurer.ClearResources() + s.Require().NoError(err) +} + +// Test1UpgradeVanilla is an end-to-end test for +// running a software upgrade proposal +func (s *SoftwareUpgradeCurrentBranchTestSuite) Test1UpgradeVanilla() { + // chain is already start the chain with software upgrade available + chainA := s.configurer.GetChainConfig(0) + chainA.WaitUntilHeight(1) + + nonValidatorNode, err := chainA.GetNodeAtIndex(2) + s.NoError(err) + + propID := nonValidatorNode.TxGovPropSubmitProposal(vanillaUpgradeFilePath, nonValidatorNode.WalletName) + s.Equal(1, propID) + // run software upgrade gov prop + // waits for block to reach + // verifies if vanilla update was done +} diff --git a/test/e2e/upgrades/vanilla.json b/test/e2e/upgrades/vanilla.json new file mode 100644 index 000000000..2b7f9ad39 --- /dev/null +++ b/test/e2e/upgrades/vanilla.json @@ -0,0 +1,14 @@ +{ + "title": "any title", + "summary": "any summary", + "messages": [ + { + "@type": "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", + "authority": "bbn10d07y265gmmuvt4z0w9aw880jnsr700jduz5f2", + "plan": { "name": "vanilla", "info": "Msg info", "height": 14 } + } + ], + "deposit": "500000000ubbn", + "initial_deposit": "500000000ubbn", + "initialDeposit": "500000000ubbn" +} From 67bda21666f673e44191c8bb2c4d39127a667343 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 17:15:40 -0300 Subject: [PATCH 04/36] feat: add query proposals to container CLI --- test/e2e/configurer/chain/queries.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index c0bb049f8..969ef69bb 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -19,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/test/e2e/util" @@ -406,6 +407,31 @@ func (n *NodeConfig) QueryWasmSmart(contract string, msg string, result any) err return nil } +func (n *NodeConfig) QueryProposal(proposalNumber int) (govtypesv1.QueryProposalResponse, error) { + path := fmt.Sprintf("cosmos/gov/v1beta1/proposals/%d", proposalNumber) + bz, err := n.QueryGRPCGateway(path, url.Values{}) + require.NoError(n.t, err) + + var resp govtypesv1.QueryProposalResponse + err = util.Cdc.UnmarshalJSON(bz, &resp) + if err != nil { + return resp, err + } + + return resp, nil +} + +func (n *NodeConfig) QueryProposals() govtypesv1.QueryProposalsResponse { + bz, err := n.QueryGRPCGateway("cosmos/gov/v1beta1/proposals", url.Values{}) + require.NoError(n.t, err) + + var resp govtypesv1.QueryProposalsResponse + err = util.Cdc.UnmarshalJSON(bz, &resp) + require.NoError(n.t, err) + + return resp +} + func (n *NodeConfig) QueryWasmSmartObject(contract string, msg string) (resultObject map[string]interface{}, err error) { err = n.QueryWasmSmart(contract, msg, &resultObject) if err != nil { From 666a2a38ef66ec899c7c4c011671e8f54934a325 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 17:16:13 -0300 Subject: [PATCH 05/36] feat: add tx gov submit prop in container CLI --- test/e2e/configurer/chain/commands.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 8d8c59b1a..6f4efc165 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -349,6 +349,25 @@ func (n *NodeConfig) TxMultisignBroadcast(walletNameMultisig, txFileFullPath str n.TxBroadcast(signedTxToBroadcast) } +func (n *NodeConfig) TxGovPropSubmitProposal(proposalJsonFilePath, from string, overallFlags ...string) int { + n.LogActionF("submitting new v1 proposal type %s", proposalJsonFilePath) + + cmd := []string{ + "babylond", "tx", "gov", "submit-proposal", proposalJsonFilePath, + fmt.Sprintf("--from=%s", from), + n.FlagChainID(), + } + + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) + require.NoError(n.t, err) + + n.WaitForNextBlocks(2) + props := n.QueryProposals() + + n.LogActionF("successfully submitted new v1 proposal type") + return int(props.Proposals[len(props.Proposals)-1].ProposalId) +} + // WriteFile writes a new file in the config dir of the node where it is volume mounted to the // babylon home inside the container and returns the full file path inside the container. func (n *NodeConfig) WriteFile(fileName, content string) (fullFilePathInContainer string) { From 22258b1d2685fe45dfd6234938f0198868e02e1a Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 21:40:06 -0300 Subject: [PATCH 06/36] feat: add query for tx debug --- test/e2e/configurer/chain/queries.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index 969ef69bb..8b652181b 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -439,3 +439,19 @@ func (n *NodeConfig) QueryWasmSmartObject(contract string, msg string) (resultOb } return resultObject, nil } + +func (n *NodeConfig) QueryTx(txHash string, overallFlags ...string) sdk.TxResponse { + cmd := []string{ + "babylond", "q", "tx", "--type=hash", txHash, "--output=json", + n.FlagChainID(), + } + + out, _, err := n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") + require.NoError(n.t, err) + + var txResp sdk.TxResponse + err = util.Cdc.UnmarshalJSON(out.Bytes(), &txResp) + require.NoError(n.t, err) + + return txResp +} From 8263d1e3c9e7f507af119b3eb0b382ea6b847411 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 21:40:55 -0300 Subject: [PATCH 07/36] fix: set min deposit to ubbn token --- test/e2e/initialization/config.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index 9e5f95a16..a2f282d24 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -6,7 +6,7 @@ import ( "path/filepath" "time" - "cosmossdk.io/math" + sdkmath "cosmossdk.io/math" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -17,6 +17,8 @@ import ( crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" staketypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" @@ -67,9 +69,9 @@ const ( ) var ( - StakeAmountIntA = math.NewInt(StakeAmountA) + StakeAmountIntA = sdkmath.NewInt(StakeAmountA) StakeAmountCoinA = sdk.NewCoin(BabylonDenom, StakeAmountIntA) - StakeAmountIntB = math.NewInt(StakeAmountB) + StakeAmountIntB = sdkmath.NewInt(StakeAmountB) StakeAmountCoinB = sdk.NewCoin(BabylonDenom, StakeAmountIntB) InitBalanceStrA = fmt.Sprintf("%d%s", BabylonBalanceA, BabylonDenom) @@ -216,6 +218,11 @@ func initGenesis(chain *internalChain, votingPeriod, expeditedVotingPeriod time. return err } + err = updateModuleGenesis(appGenState, govtypes.ModuleName, &govv1beta1.GenesisState{}, updateGovGenesis) + if err != nil { + return err + } + err = updateModuleGenesis(appGenState, minttypes.ModuleName, &minttypes.GenesisState{}, updateMintGenesis) if err != nil { return err @@ -288,6 +295,10 @@ func updateBankGenesis(bankGenState *banktypes.GenesisState) { }) } +func updateGovGenesis(govGenState *govv1beta1.GenesisState) { + govGenState.DepositParams.MinDeposit = sdk.NewCoins(sdk.NewCoin(BabylonDenom, sdkmath.NewInt(100))) +} + func updateMintGenesis(mintGenState *minttypes.GenesisState) { mintGenState.Params.MintDenom = BabylonDenom } @@ -299,7 +310,7 @@ func updateStakeGenesis(stakeGenState *staketypes.GenesisState) { MaxEntries: 7, HistoricalEntries: 10000, UnbondingTime: staketypes.DefaultUnbondingTime, - MinCommissionRate: math.LegacyZeroDec(), + MinCommissionRate: sdkmath.LegacyZeroDec(), } } From 5e9d937078051027fc62bb690b5d5111c1063148 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 22:41:13 -0300 Subject: [PATCH 08/36] fix: set gov prop time in genstate gov --- test/e2e/configurer/chain/node.go | 9 +++++++++ test/e2e/initialization/config.go | 11 +++++++---- test/e2e/upgrades/vanilla.json | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/test/e2e/configurer/chain/node.go b/test/e2e/configurer/chain/node.go index 8e185ec51..162bdeb31 100644 --- a/test/e2e/configurer/chain/node.go +++ b/test/e2e/configurer/chain/node.go @@ -153,6 +153,15 @@ func (n *NodeConfig) WaitForNextBlocks(numberOfBlocks uint64) { }, fmt.Sprintf("Timed out waiting for block %d. Current height is: %d", latest, blockToWait)) } +func (n *NodeConfig) WaitForBlockHeight(blkHeight uint64) { + latest := n.LatestBlockNumber() + if blkHeight < latest { + return + } + blocksToWait := blkHeight - latest + n.WaitForNextBlocks(blocksToWait) +} + func (n *NodeConfig) extractOperatorAddressIfValidator() error { if !n.IsValidator { n.t.Logf("node (%s) is not a validator, skipping", n.Name) diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index a2f282d24..9af54728e 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -18,7 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" staketypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" @@ -218,7 +218,7 @@ func initGenesis(chain *internalChain, votingPeriod, expeditedVotingPeriod time. return err } - err = updateModuleGenesis(appGenState, govtypes.ModuleName, &govv1beta1.GenesisState{}, updateGovGenesis) + err = updateModuleGenesis(appGenState, govtypes.ModuleName, &govv1.GenesisState{}, updateGovGenesis) if err != nil { return err } @@ -295,8 +295,11 @@ func updateBankGenesis(bankGenState *banktypes.GenesisState) { }) } -func updateGovGenesis(govGenState *govv1beta1.GenesisState) { - govGenState.DepositParams.MinDeposit = sdk.NewCoins(sdk.NewCoin(BabylonDenom, sdkmath.NewInt(100))) +func updateGovGenesis(govGenState *govv1.GenesisState) { + govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(BabylonDenom, sdkmath.NewInt(100))) + + votingPeriod := time.Duration(time.Second * 10) + govGenState.Params.VotingPeriod = &votingPeriod } func updateMintGenesis(mintGenState *minttypes.GenesisState) { diff --git a/test/e2e/upgrades/vanilla.json b/test/e2e/upgrades/vanilla.json index 2b7f9ad39..674846739 100644 --- a/test/e2e/upgrades/vanilla.json +++ b/test/e2e/upgrades/vanilla.json @@ -5,7 +5,7 @@ { "@type": "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", "authority": "bbn10d07y265gmmuvt4z0w9aw880jnsr700jduz5f2", - "plan": { "name": "vanilla", "info": "Msg info", "height": 14 } + "plan": { "name": "vanilla", "info": "Msg info", "height": 10 } } ], "deposit": "500000000ubbn", From de2aae7a10454e703aca011395dba24cb7fa26ec Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 22:43:15 -0300 Subject: [PATCH 09/36] chore: add vote to gov prop --- test/e2e/configurer/chain/chain.go | 11 +++++++- test/e2e/configurer/chain/commands.go | 23 ++++++++++++++-- ...oftware_upgrade_current_branch_e2e_test.go | 27 +++++++------------ 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/test/e2e/configurer/chain/chain.go b/test/e2e/configurer/chain/chain.go index 4d5e1ec03..2c16e9f4b 100644 --- a/test/e2e/configurer/chain/chain.go +++ b/test/e2e/configurer/chain/chain.go @@ -2,10 +2,12 @@ package chain import ( "fmt" - ibctesting "github.com/cosmos/ibc-go/v8/testing" "testing" "time" + govv1 "cosmossdk.io/api/cosmos/gov/v1" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + coretypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -173,3 +175,10 @@ func (c *Config) GetNodeAtIndex(nodeIndex int) (*NodeConfig, error) { } return c.NodeConfigs[nodeIndex], nil } + +// TxGovVoteFromAllNodes votes in a gov prop from all nodes wallet. +func (c *Config) TxGovVoteFromAllNodes(propID int, option govv1.VoteOption, overallFlags ...string) { + for _, n := range c.NodeConfigs { + n.TxGovVote(n.WalletName, propID, option, overallFlags...) + } +} diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 6f4efc165..2922f5959 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -12,6 +12,7 @@ import ( "strings" "time" + govv1 "cosmossdk.io/api/cosmos/gov/v1" txformat "github.com/babylonchain/babylon/btctxformatter" "github.com/babylonchain/babylon/test/e2e/containers" "github.com/babylonchain/babylon/test/e2e/initialization" @@ -349,25 +350,43 @@ func (n *NodeConfig) TxMultisignBroadcast(walletNameMultisig, txFileFullPath str n.TxBroadcast(signedTxToBroadcast) } +// TxGovPropSubmitProposal submits a governance proposal from the file inside the container, +// if the file is local, remind to add it to the mounting point in container. func (n *NodeConfig) TxGovPropSubmitProposal(proposalJsonFilePath, from string, overallFlags ...string) int { n.LogActionF("submitting new v1 proposal type %s", proposalJsonFilePath) cmd := []string{ "babylond", "tx", "gov", "submit-proposal", proposalJsonFilePath, fmt.Sprintf("--from=%s", from), - n.FlagChainID(), } _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) require.NoError(n.t, err) - n.WaitForNextBlocks(2) + n.WaitForNextBlock() + props := n.QueryProposals() + require.GreaterOrEqual(n.t, len(props.Proposals), 1) n.LogActionF("successfully submitted new v1 proposal type") return int(props.Proposals[len(props.Proposals)-1].ProposalId) } +// TxGovVote votes in a governance proposal +func (n *NodeConfig) TxGovVote(from string, propID int, option govv1.VoteOption, overallFlags ...string) { + n.LogActionF("submitting vote %s to prop %d", option, propID) + + cmd := []string{ + "babylond", "tx", "gov", "vote", string(propID), option.String(), + fmt.Sprintf("--from=%s", from), + } + + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) + require.NoError(n.t, err) + + n.LogActionF("successfully submitted vote %s to prop %d", option, propID) +} + // WriteFile writes a new file in the config dir of the node where it is volume mounted to the // babylon home inside the container and returns the full file path inside the container. func (n *NodeConfig) WriteFile(fileName, content string) (fullFilePathInContainer string) { diff --git a/test/e2e/software_upgrade_current_branch_e2e_test.go b/test/e2e/software_upgrade_current_branch_e2e_test.go index bb319a841..731033bc9 100644 --- a/test/e2e/software_upgrade_current_branch_e2e_test.go +++ b/test/e2e/software_upgrade_current_branch_e2e_test.go @@ -1,25 +1,12 @@ package e2e import ( + govv1 "cosmossdk.io/api/cosmos/gov/v1" "github.com/stretchr/testify/suite" "github.com/babylonchain/babylon/test/e2e/configurer" ) -var ( -// r = rand.New(rand.NewSource(time.Now().Unix())) -// net = &chaincfg.SimNetParams -// // finality provider -// fpBTCSK, _, _ = datagen.GenRandomBTCKeyPair(r) -// cacheFP *bstypes.FinalityProvider -// // BTC delegation -// delBTCSK, delBTCPK, _ = datagen.GenRandomBTCKeyPair(r) -// // covenant -// covenantSKs, _, covenantQuorum = bstypes.DefaultCovenantCommittee() - -// stakingValue = int64(2 * 10e8) -) - const ( // Mount path in container is fmt.Sprintf("%s/upgrades:/upgrades", pwd) vanillaUpgradeFilePath = "/upgrades/vanilla.json" @@ -62,9 +49,15 @@ func (s *SoftwareUpgradeCurrentBranchTestSuite) Test1UpgradeVanilla() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) + // software upgrade gov prop propID := nonValidatorNode.TxGovPropSubmitProposal(vanillaUpgradeFilePath, nonValidatorNode.WalletName) s.Equal(1, propID) - // run software upgrade gov prop - // waits for block to reach - // verifies if vanilla update was done + + // vote from all nodes + chainA.TxGovVoteFromAllNodes(propID, govv1.VoteOption_VOTE_OPTION_YES) + + // waits for block to reach + 1 + nonValidatorNode.WaitForBlockHeight(11) + + // verifies vanilla upgrade was completed } From 3cd33d4550292dc01132d583d4b45dd30df1e1a1 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Mon, 22 Jul 2024 23:16:19 -0300 Subject: [PATCH 10/36] test: upgrade fails due to BINARY UPDATED BEFORE TRIGGER --- test/e2e/configurer/chain/commands.go | 2 +- test/e2e/configurer/chain/node.go | 10 +++---- test/e2e/configurer/chain/queries.go | 8 +++--- test/e2e/e2e_test.go | 4 +-- ...oftware_upgrade_current_branch_e2e_test.go | 26 +++++++++++++++++-- test/e2e/upgrades/vanilla.json | 2 +- 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 2922f5959..bb789ec4b 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -377,7 +377,7 @@ func (n *NodeConfig) TxGovVote(from string, propID int, option govv1.VoteOption, n.LogActionF("submitting vote %s to prop %d", option, propID) cmd := []string{ - "babylond", "tx", "gov", "vote", string(propID), option.String(), + "babylond", "tx", "gov", "vote", fmt.Sprintf("%d", propID), option.String(), fmt.Sprintf("--from=%s", from), } diff --git a/test/e2e/configurer/chain/node.go b/test/e2e/configurer/chain/node.go index 162bdeb31..2a8f1ccd5 100644 --- a/test/e2e/configurer/chain/node.go +++ b/test/e2e/configurer/chain/node.go @@ -154,12 +154,10 @@ func (n *NodeConfig) WaitForNextBlocks(numberOfBlocks uint64) { } func (n *NodeConfig) WaitForBlockHeight(blkHeight uint64) { - latest := n.LatestBlockNumber() - if blkHeight < latest { - return - } - blocksToWait := blkHeight - latest - n.WaitForNextBlocks(blocksToWait) + n.WaitForCondition(func() bool { + newLatest := n.LatestBlockNumber() + return newLatest > blkHeight + }, fmt.Sprintf("Timed out waiting for block %d.", blkHeight)) } func (n *NodeConfig) extractOperatorAddressIfValidator() error { diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index 8b652181b..f7b2c9cb5 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -407,18 +407,16 @@ func (n *NodeConfig) QueryWasmSmart(contract string, msg string, result any) err return nil } -func (n *NodeConfig) QueryProposal(proposalNumber int) (govtypesv1.QueryProposalResponse, error) { +func (n *NodeConfig) QueryProposal(proposalNumber int) govtypesv1.QueryProposalResponse { path := fmt.Sprintf("cosmos/gov/v1beta1/proposals/%d", proposalNumber) bz, err := n.QueryGRPCGateway(path, url.Values{}) require.NoError(n.t, err) var resp govtypesv1.QueryProposalResponse err = util.Cdc.UnmarshalJSON(bz, &resp) - if err != nil { - return resp, err - } + require.NoError(n.t, err) - return resp, nil + return resp } func (n *NodeConfig) QueryProposals() govtypesv1.QueryProposalsResponse { diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index d27b66acf..0eb9240dd 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -36,7 +36,7 @@ func TestBTCStakingTestSuite(t *testing.T) { suite.Run(t, new(BTCStakingTestSuite)) } -// TestSoftwareUpgradeTestSuite tests software upgrade protocol end-to-end -func TestSoftwareUpgradeTestSuite(t *testing.T) { +// TestSoftwareUpgradeCurrentBranchTestSuite tests software upgrade protocol end-to-end +func TestSoftwareUpgradeCurrentBranchTestSuite(t *testing.T) { suite.Run(t, new(SoftwareUpgradeCurrentBranchTestSuite)) } diff --git a/test/e2e/software_upgrade_current_branch_e2e_test.go b/test/e2e/software_upgrade_current_branch_e2e_test.go index 731033bc9..298285437 100644 --- a/test/e2e/software_upgrade_current_branch_e2e_test.go +++ b/test/e2e/software_upgrade_current_branch_e2e_test.go @@ -1,6 +1,8 @@ package e2e import ( + "fmt" + govv1 "cosmossdk.io/api/cosmos/gov/v1" "github.com/stretchr/testify/suite" @@ -49,6 +51,8 @@ func (s *SoftwareUpgradeCurrentBranchTestSuite) Test1UpgradeVanilla() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) + fpsBeforeUpgrade := nonValidatorNode.QueryFinalityProviders() + // software upgrade gov prop propID := nonValidatorNode.TxGovPropSubmitProposal(vanillaUpgradeFilePath, nonValidatorNode.WalletName) s.Equal(1, propID) @@ -56,8 +60,26 @@ func (s *SoftwareUpgradeCurrentBranchTestSuite) Test1UpgradeVanilla() { // vote from all nodes chainA.TxGovVoteFromAllNodes(propID, govv1.VoteOption_VOTE_OPTION_YES) - // waits for block to reach + 1 - nonValidatorNode.WaitForBlockHeight(11) + tx := nonValidatorNode.QueryProposal(propID) + fmt.Printf("\n prop %+v", tx) + + // waits for block to reach from plan + 1 + // tricky to get current heigth and set it in the json, because the file is + // load at the mounting point of the node it could be created at runtime and + // stored in the filesystem of the container + nonValidatorNode.WaitForBlockHeight(21) + + tx = nonValidatorNode.QueryProposal(propID) + fmt.Printf("\n prop %+v", tx) // verifies vanilla upgrade was completed + fpsAfterUpgrade := nonValidatorNode.QueryFinalityProviders() + s.Equal(len(fpsBeforeUpgrade)+1, len(fpsAfterUpgrade)) + + // docker logs -f + // 2:09AM ERR BINARY UPDATED BEFORE TRIGGER! UPGRADE "vanilla" - in binary but not executed on chain. Downgrade your binary module=x/upgrade + // 2:09AM ERR error in proxyAppConn.FinalizeBlock err="BINARY UPDATED BEFORE TRIGGER! UPGRADE \"vanilla\" - in binary but not executed on chain. Downgrade your binary" module=state + tx = nonValidatorNode.QueryProposal(propID) + fmt.Printf("\n prop %+v", tx) + } diff --git a/test/e2e/upgrades/vanilla.json b/test/e2e/upgrades/vanilla.json index 674846739..c9fd6c9d3 100644 --- a/test/e2e/upgrades/vanilla.json +++ b/test/e2e/upgrades/vanilla.json @@ -5,7 +5,7 @@ { "@type": "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", "authority": "bbn10d07y265gmmuvt4z0w9aw880jnsr700jduz5f2", - "plan": { "name": "vanilla", "info": "Msg info", "height": 10 } + "plan": { "name": "vanilla", "info": "Msg info", "height": 20 } } ], "deposit": "500000000ubbn", From 8f981bd2c1a13cc0765feb114be22fb162f2f425 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 12:59:24 -0300 Subject: [PATCH 11/36] chore: mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 98badadb7..54416cadb 100644 --- a/go.mod +++ b/go.mod @@ -64,6 +64,7 @@ require ( github.com/vulpine-io/io-test v1.0.0 go.uber.org/zap v1.26.0 golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 + golang.org/x/sync v0.7.0 google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de ) @@ -247,7 +248,6 @@ require ( golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.7.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.20.0 // indirect google.golang.org/api v0.162.0 // indirect From b58126c7fdc565650126d3dc1af485107d34203a Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 21:59:10 -0300 Subject: [PATCH 12/36] feat: add directives to build babylon from specific version and tag as before upgrade --- Makefile | 19 +++++++++++++++++-- contrib/images/Makefile | 14 +++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 72eca733f..70b7c4238 100644 --- a/Makefile +++ b/Makefile @@ -205,6 +205,17 @@ build-docs: diagrams ### Tests & Simulation ### ############################################################################### +# Executed to build the binary for chain initialization, one of +## chain => test/e2e/initialization/chain/main.go +## node => test/e2e/initialization/node/main.go +e2e-build-script: + mkdir -p $(BUILDDIR) + go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./test/e2e/initialization/$(E2E_SCRIPT_NAME) + +############################################################################### +### Tests & Simulation ### +############################################################################### + test: test-unit test-all: test-unit test-ledger-mock test-race test-cover @@ -240,7 +251,7 @@ endif .PHONY: run-tests test test-all $(TEST_TARGETS) -test-e2e: build-docker +test-e2e: build-docker-e2e go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 --tags=e2e test-sim-nondeterminism: @@ -412,10 +423,14 @@ proto-lint: build-docker: $(MAKE) -C contrib/images babylond +build-docker-e2e: build-docker + $(MAKE) -C contrib/images babylond-before-upgrade + $(MAKE) -C contrib/images e2e-init-chain + build-cosmos-relayer-docker: $(MAKE) -C contrib/images cosmos-relayer -.PHONY: build-docker build-cosmos-relayer-docker +.PHONY: build-docker build-docker-e2e build-cosmos-relayer-docker ############################################################################### ### Localnet ### diff --git a/contrib/images/Makefile b/contrib/images/Makefile index 3b9d0818e..7ca6df2dc 100644 --- a/contrib/images/Makefile +++ b/contrib/images/Makefile @@ -1,17 +1,25 @@ RELAYER_TAG := $(shell grep '^ENV RELAYER_TAG' cosmos-relayer/Dockerfile | cut -f3 -d\ ) +BABYLON_FULL_PATH := $(shell git rev-parse --show-toplevel) all: babylond cosmos-relayer babylond: babylond-rmi - docker build --tag babylonchain/babylond -f babylond/Dockerfile \ - $(shell git rev-parse --show-toplevel) + docker build --tag babylonchain/babylond -f babylond/Dockerfile ${BABYLON_FULL_PATH} + +babylond-before-upgrade: + docker rmi babylonchain/babylond-before-upgrade 2>/dev/null; true && \ + docker build --tag babylonchain/babylond-before-upgrade -f babylond/Dockerfile \ + --build-arg VERSION="a33a3344bb44bde2f3374d3cbf919abb942c341a" ${BABYLON_FULL_PATH} babylond-rmi: docker rmi babylonchain/babylond 2>/dev/null; true +e2e-init-chain: + @DOCKER_BUILDKIT=1 docker build -t babylonchain/babylond-e2e-init-chain --build-arg E2E_SCRIPT_NAME=chain --platform=linux/x86_64 -f e2e-initialization/init.Dockerfile ${BABYLON_FULL_PATH} + cosmos-relayer: cosmos-relayer-rmi docker build --tag babylonchain/cosmos-relayer:${RELAYER_TAG} -f cosmos-relayer/Dockerfile \ - $(shell git rev-parse --show-toplevel)/contrib/images/cosmos-relayer + ${BABYLON_FULL_PATH}/contrib/images/cosmos-relayer docker tag babylonchain/cosmos-relayer:${RELAYER_TAG} babylonchain/cosmos-relayer:latest cosmos-relayer-rmi: From e0aa707f47b7b8d36f69949d437de28ed306abd4 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 22:44:08 -0300 Subject: [PATCH 13/36] chore: add comment for TODO rmv upgrade for mainnet --- app/app.go | 1 + 1 file changed, 1 insertion(+) diff --git a/app/app.go b/app/app.go index cd05f8084..1cc9347ca 100644 --- a/app/app.go +++ b/app/app.go @@ -159,6 +159,7 @@ var ( } // software upgrades and forks + // TODO: REMOVE UPGRADE BEFORE MAINNET, used for e2e testing Upgrades = []upgrades.Upgrade{ vanilla.Upgrade, } From f47f382f438d52c762e3ecfbb2a5269319d97938 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:02:00 -0300 Subject: [PATCH 14/36] chore: add clean docker directive --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 70b7c4238..0d2b6ffce 100644 --- a/Makefile +++ b/Makefile @@ -419,6 +419,7 @@ proto-lint: ############################################################################### ### Docker ### ############################################################################### +dockerNetworkList=$($(DOCKER) network ls --filter name=bbn-testnet --format {{.ID}}) build-docker: $(MAKE) -C contrib/images babylond @@ -430,7 +431,10 @@ build-docker-e2e: build-docker build-cosmos-relayer-docker: $(MAKE) -C contrib/images cosmos-relayer -.PHONY: build-docker build-docker-e2e build-cosmos-relayer-docker +clean-docker-network: + $(DOCKER) network rm ${dockerNetworkList} + +.PHONY: build-docker build-docker-e2e build-cosmos-relayer-docker clean-docker-network ############################################################################### ### Localnet ### From 7943a8fc9c7c8605c6bafbca9bc578ea7f1b612d Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:02:33 -0300 Subject: [PATCH 15/36] chore: add fetch for commit hash in babylond docker file versioned --- contrib/images/babylond/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/images/babylond/Dockerfile b/contrib/images/babylond/Dockerfile index 2e8add214..326d5fa7b 100644 --- a/contrib/images/babylond/Dockerfile +++ b/contrib/images/babylond/Dockerfile @@ -23,6 +23,7 @@ RUN go mod download COPY ./ /go/src/github.com/babylonchain/babylon/ # If version is set, then checkout this version RUN if [ -n "${VERSION}" ]; then \ + git fetch origin ${VERSION}; \ git checkout -f ${VERSION}; \ fi From ac78533f238bd67548a0f68757db7f120a28444b Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:02:57 -0300 Subject: [PATCH 16/36] fix: deterministic upgrade --- app/upgrades/vanilla/upgrades.go | 42 +++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/app/upgrades/vanilla/upgrades.go b/app/upgrades/vanilla/upgrades.go index 156e5de72..c46b94b63 100644 --- a/app/upgrades/vanilla/upgrades.go +++ b/app/upgrades/vanilla/upgrades.go @@ -45,18 +45,48 @@ func propVanilla( accountKeeper *authkeeper.AccountKeeper, bsKeeper *btcstakingkeeper.Keeper, ) { - // remove an account + // remove the account with higher number and the lowest is the new fp addr allAccounts := accountKeeper.GetAllAccounts(ctx) - accountKeeper.RemoveAccount(ctx, allAccounts[len(allAccounts)-1]) - // insert a FP - sk, err := btcec.NewPrivateKey() + var ( + accToRemove sdk.AccountI + accFp sdk.AccountI + ) + heighestAccNumber, lowestAccNumber := uint64(0), uint64(len(allAccounts)) + + for _, acc := range allAccounts { + accNumber := acc.GetAccountNumber() + if accNumber > heighestAccNumber { + heighestAccNumber = accNumber + accToRemove = acc + } + if accNumber < lowestAccNumber { + lowestAccNumber = accNumber + accFp = acc + } + } + + accountKeeper.RemoveAccount(ctx, accToRemove) + + // insert a FP from predefined public key + pk, err := btcec.ParsePubKey( + []byte{0x06, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, + 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, + 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, + 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98, 0x48, 0x3a, + 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, + 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, + 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, + 0x10, 0xd4, 0xb8, + }, + ) if err != nil { panic(err) } - btcPK := bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()) + + btcPK := bbn.NewBIP340PubKeyFromBTCPK(pk) fp := &bstypes.FinalityProvider{ - Addr: allAccounts[0].GetAddress().String(), + Addr: accFp.GetAddress().String(), BtcPk: btcPK, } bsKeeper.SetFinalityProvider(ctx, fp) From eccb4a2824ea704b306b4117e6026271fdfbb637 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:05:05 -0300 Subject: [PATCH 17/36] feat: add upgrade and initialization needed for software upgrade prop --- .../images/e2e-initialization/init.Dockerfile | 49 ++++ test/e2e/configurer/config/constants.go | 13 + test/e2e/configurer/factory.go | 36 ++- test/e2e/configurer/setup.go | 28 +- test/e2e/configurer/upgrade.go | 265 ++++++++++++++++++ test/e2e/containers/config.go | 38 ++- test/e2e/containers/containers.go | 41 ++- test/e2e/upgrades/vanilla.json | 2 +- 8 files changed, 446 insertions(+), 26 deletions(-) create mode 100644 contrib/images/e2e-initialization/init.Dockerfile create mode 100644 test/e2e/configurer/upgrade.go diff --git a/contrib/images/e2e-initialization/init.Dockerfile b/contrib/images/e2e-initialization/init.Dockerfile new file mode 100644 index 000000000..a929bf706 --- /dev/null +++ b/contrib/images/e2e-initialization/init.Dockerfile @@ -0,0 +1,49 @@ +FROM golang:1.21 as build-env + +ARG E2E_SCRIPT_NAME + +# TARGETPLATFORM should be one of linux/amd64 or linux/arm64. +ARG TARGETPLATFORM="linux/amd64" + +# Install cli tools for building and final image +RUN apt-get update && apt-get install -y make git bash gcc curl jq + +WORKDIR /go/src/github.com/babylonchain/babylon + +# First cache dependencies +COPY go.mod go.sum /go/src/github.com/babylonchain/babylon/ +RUN go mod download + +# Copy everything else +COPY ./ /go/src/github.com/babylonchain/babylon/ + +RUN LEDGER_ENABLED=false LINK_STATICALLY=false E2E_SCRIPT_NAME=${E2E_SCRIPT_NAME} make e2e-build-script + +FROM debian:bookworm-slim AS run + +# Create a user +RUN addgroup --gid 1137 --system babylon && adduser --uid 1137 --gid 1137 --system --home /home/babylon babylon +RUN apt-get update && apt-get install -y bash curl jq wget + +COPY --from=build-env /go/src/github.com/babylonchain/babylon/go.mod /tmp +RUN WASMVM_VERSION=$(grep github.com/CosmWasm/wasmvm /tmp/go.mod | cut -d' ' -f2) && \ + wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/libwasmvm.$(uname -m).so \ + -O /lib/libwasmvm.$(uname -m).so && \ + # verify checksum + wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/checksums.txt -O /tmp/checksums.txt && \ + sha256sum /lib/libwasmvm.$(uname -m).so | grep $(cat /tmp/checksums.txt | grep libwasmvm.$(uname -m) | cut -d ' ' -f 1) + +# Args only last for a single build stage - renew +ARG E2E_SCRIPT_NAME + +COPY --from=build-env /go/src/github.com/babylonchain/babylon/build/${E2E_SCRIPT_NAME} /bin/${E2E_SCRIPT_NAME} + +ENV HOME /babylond +WORKDIR $HOME + +# Docker ARGs are not expanded in ENTRYPOINT in the exec mode. At the same time, +# it is impossible to add CMD arguments when running a container in the shell mode. +# As a workaround, we create the entrypoint.sh script to bypass these issues. +RUN echo "#!/bin/bash\n${E2E_SCRIPT_NAME} \"\$@\"" >> entrypoint.sh && chmod +x entrypoint.sh + +ENTRYPOINT ["./entrypoint.sh"] diff --git a/test/e2e/configurer/config/constants.go b/test/e2e/configurer/config/constants.go index 09c584507..9ba3a0a09 100644 --- a/test/e2e/configurer/config/constants.go +++ b/test/e2e/configurer/config/constants.go @@ -7,4 +7,17 @@ const ( PropVoteBlocks float32 = 1.2 // PropBufferBlocks number of blocks used as a calculation buffer PropBufferBlocks float32 = 6 + + // Upgrades + // ForkHeightPreUpgradeOffset how many blocks we allow for fork to run pre upgrade state creation + ForkHeightPreUpgradeOffset int64 = 60 + // MaxRetries for json unmarshalling init chain + MaxRetries = 60 + // PropSubmitBlocks estimated number of blocks it takes to submit for a proposal + PropSubmitBlocks float32 = 1 + // Minimum deposit value for a proposal to enter a voting period. + MinDepositValue = 1000000 + + // VanillaUpgradeFilePath upgrade vanilla testing + VanillaUpgradeFilePath = "/upgrades/vanilla.json" ) diff --git a/test/e2e/configurer/factory.go b/test/e2e/configurer/factory.go index 0182a40dc..c9aa4eb9b 100644 --- a/test/e2e/configurer/factory.go +++ b/test/e2e/configurer/factory.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/babylonchain/babylon/test/e2e/configurer/chain" + "github.com/babylonchain/babylon/test/e2e/configurer/config" "github.com/babylonchain/babylon/test/e2e/containers" "github.com/babylonchain/babylon/test/e2e/initialization" zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" @@ -114,7 +115,7 @@ var ( // TODO currently only one configuration is available. Consider testing upgrades // when necessary func NewBTCTimestampingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, false) + containerManager, err := containers.NewManager(isDebugLogEnabled, false, false) if err != nil { return nil, err } @@ -130,7 +131,7 @@ func NewBTCTimestampingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configu } func NewIBCTransferConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, false) + containerManager, err := containers.NewManager(isDebugLogEnabled, false, false) if err != nil { return nil, err } @@ -147,7 +148,7 @@ func NewIBCTransferConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, // NewBTCTimestampingPhase2Configurer returns a new Configurer for BTC timestamping service (phase 2). func NewBTCTimestampingPhase2Configurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, false) + containerManager, err := containers.NewManager(isDebugLogEnabled, false, false) if err != nil { return nil, err } @@ -164,7 +165,7 @@ func NewBTCTimestampingPhase2Configurer(t *testing.T, isDebugLogEnabled bool) (C // NewBTCTimestampingPhase2RlyConfigurer returns a new Configurer for BTC timestamping service (phase 2), using the Go relayer (rly). func NewBTCTimestampingPhase2RlyConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, true) + containerManager, err := containers.NewManager(isDebugLogEnabled, true, false) if err != nil { return nil, err } @@ -181,7 +182,7 @@ func NewBTCTimestampingPhase2RlyConfigurer(t *testing.T, isDebugLogEnabled bool) // NewBTCStakingConfigurer returns a new Configurer for BTC staking service func NewBTCStakingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, false) + containerManager, err := containers.NewManager(isDebugLogEnabled, false, false) if err != nil { return nil, err } @@ -196,9 +197,9 @@ func NewBTCStakingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, ), nil } -// NewSoftwareUpgradeTest returns a new Configurer for Software Upgrade testing -func NewSoftwareUpgradeTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, false) +// NewSoftwareUpgradeCurrentBranchTest returns a new Configurer for Software Upgrade testing +func NewSoftwareUpgradeCurrentBranchTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { + containerManager, err := containers.NewManager(isDebugLogEnabled, false, false) if err != nil { return nil, err } @@ -212,3 +213,22 @@ func NewSoftwareUpgradeTest(t *testing.T, isDebugLogEnabled bool) (Configurer, e containerManager, ), nil } + +// NewSoftwareUpgradeTest returns a new Configurer for Software Upgrade testing +func NewSoftwareUpgradeTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { + containerManager, err := containers.NewManager(isDebugLogEnabled, false, true) + if err != nil { + return nil, err + } + + return NewUpgradeConfigurer(t, + []*chain.Config{ + // we only need 1 chain for testing upgrade + chain.New(t, containerManager, initialization.ChainAID, validatorConfigsChainA, nil), + }, + withUpgrade(baseSetup), // base set up with upgrade + containerManager, + config.VanillaUpgradeFilePath, + 0, + ), nil +} diff --git a/test/e2e/configurer/setup.go b/test/e2e/configurer/setup.go index 21308c458..ae2ce6a1b 100644 --- a/test/e2e/configurer/setup.go +++ b/test/e2e/configurer/setup.go @@ -1,6 +1,9 @@ package configurer -import "time" +import ( + "fmt" + "time" +) type setupFn func(configurer Configurer) error @@ -77,3 +80,26 @@ func withIBCTransferChannel(setupHandler setupFn) setupFn { return nil } } + +func withUpgrade(setupHandler setupFn) setupFn { + return func(configurer Configurer) error { + if err := setupHandler(configurer); err != nil { + return err + } + + upgradeConfigurer, ok := configurer.(*UpgradeConfigurer) + if !ok { + return fmt.Errorf("to run with upgrade, %v must be set during initialization", &UpgradeConfigurer{}) + } + + if err := upgradeConfigurer.CreatePreUpgradeState(); err != nil { + return err + } + + if err := upgradeConfigurer.RunUpgrade(); err != nil { + return err + } + + return nil + } +} diff --git a/test/e2e/configurer/upgrade.go b/test/e2e/configurer/upgrade.go new file mode 100644 index 000000000..ba3080614 --- /dev/null +++ b/test/e2e/configurer/upgrade.go @@ -0,0 +1,265 @@ +package configurer + +import ( + "encoding/json" + "fmt" + "os" + "sync" + "testing" + "time" + + govv1 "cosmossdk.io/api/cosmos/gov/v1" + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + appparams "github.com/babylonchain/babylon/app/params" + "github.com/babylonchain/babylon/test/e2e/configurer/chain" + "github.com/babylonchain/babylon/test/e2e/configurer/config" + "github.com/babylonchain/babylon/test/e2e/containers" + "github.com/babylonchain/babylon/test/e2e/initialization" +) + +type UpgradeSettings struct { + IsEnabled bool + Version string + ForkHeight int64 // non-zero height implies that this is a fork upgrade. +} + +type UpgradeConfigurer struct { + baseConfigurer + upgradeJsonFilePath string + forkHeight int64 // forkHeight > 0 implies that this is a fork upgrade. Otherwise, proposal upgrade. +} + +var _ Configurer = (*UpgradeConfigurer)(nil) + +// NewUpgradeConfigurer returns a upgrade configurer, if forkHeight is bigger +// than 0 it implies that it is a fork upgrade that does not pass by a gov prop +// if it is set to zero it runs the upgrade by the gov prop. +func NewUpgradeConfigurer(t *testing.T, chainConfigs []*chain.Config, setupTests setupFn, containerManager *containers.Manager, upgradePlanFilePath string, forkHeight int64) Configurer { + t.Helper() + return &UpgradeConfigurer{ + baseConfigurer: baseConfigurer{ + chainConfigs: chainConfigs, + containerManager: containerManager, + setupTests: setupTests, + syncUntilHeight: forkHeight + defaultSyncUntilHeight, + t: t, + }, + forkHeight: forkHeight, + upgradeJsonFilePath: upgradePlanFilePath, + } +} + +func (uc *UpgradeConfigurer) ConfigureChains() error { + errCh := make(chan error, len(uc.chainConfigs)) + var wg sync.WaitGroup + + for _, chainConfig := range uc.chainConfigs { + wg.Add(1) + go func(cc *chain.Config) { + defer wg.Done() + if err := uc.ConfigureChain(cc); err != nil { + errCh <- err + } + }(chainConfig) + } + + // Wait for all goroutines to complete + wg.Wait() + close(errCh) + + // Check if any of the goroutines returned an error + for err := range errCh { + if err != nil { + return err + } + } + + return nil +} + +func (uc *UpgradeConfigurer) ConfigureChain(chainConfig *chain.Config) error { + uc.t.Logf("starting upgrade e2e infrastructure for chain-id: %s", chainConfig.Id) + tmpDir, err := os.MkdirTemp("", "bbn-e2e-testnet-") + if err != nil { + return err + } + + validatorConfigBytes, err := json.Marshal(chainConfig.ValidatorInitConfigs) + if err != nil { + return err + } + + forkHeight := uc.forkHeight + if forkHeight > 0 { + forkHeight = forkHeight - config.ForkHeightPreUpgradeOffset + } + + chainInitResource, err := uc.containerManager.RunChainInitResource(chainConfig.Id, int(chainConfig.VotingPeriod), int(chainConfig.ExpeditedVotingPeriod), validatorConfigBytes, tmpDir, int(forkHeight)) + if err != nil { + return err + } + + fileName := fmt.Sprintf("%v/%v-encode", tmpDir, chainConfig.Id) + uc.t.Logf("serialized init file for chain-id %v: %v", chainConfig.Id, fileName) + + // loop through the reading and unmarshaling of the init file a total of maxRetries or until error is nil + // without this, test attempts to unmarshal file before docker container is finished writing + var initializedChain initialization.Chain + for i := 0; i < config.MaxRetries; i++ { + initializedChainBytes, _ := os.ReadFile(fileName) + err = json.Unmarshal(initializedChainBytes, &initializedChain) + if err == nil { + break + } + + if i == config.MaxRetries-1 { + return err + } + + if i > 0 { + time.Sleep(1 * time.Second) + } + } + if err := uc.containerManager.PurgeResource(chainInitResource); err != nil { + return err + } + uc.initializeChainConfigFromInitChain(&initializedChain, chainConfig) + return nil +} + +func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { + // send a few bank transfers simulating state data + amountToSend := sdk.NewCoin(appparams.BaseCoinUnit, sdkmath.NewInt(1000000)) // 1bbn + for _, chain := range uc.chainConfigs { + firstNode := chain.NodeConfigs[0] + for i := 1; i < len(chain.NodeConfigs); i++ { + nodeI := chain.NodeConfigs[i] + firstNode.BankSendFromNode(nodeI.PublicAddress, amountToSend.String()) + } + } + + return nil +} + +func (uc *UpgradeConfigurer) RunSetup() error { + return uc.setupTests(uc) +} + +func (uc *UpgradeConfigurer) RunUpgrade() error { + var err error + if uc.forkHeight > 0 { + uc.runForkUpgrade() + } else { + err = uc.runProposalUpgrade() + } + if err != nil { + return err + } + + // Check if the nodes are running + for chainIndex, chainConfig := range uc.chainConfigs { + chain := uc.baseConfigurer.GetChainConfig(chainIndex) + for validatorIdx := range chainConfig.NodeConfigs { + node := chain.NodeConfigs[validatorIdx] + // Check node status + _, err = node.Status() + if err != nil { + uc.t.Errorf("node is not running after upgrade, chain-id %s, node %s", chainConfig.Id, node.Name) + return err + } + uc.t.Logf("node %s upgraded successfully, address %s", node.Name, node.PublicAddress) + } + } + return nil +} + +func (uc *UpgradeConfigurer) runProposalUpgrade() error { + // submit, deposit, and vote for upgrade proposal + // prop height = current height + voting period + time it takes to submit proposal + small buffer + for _, chainConfig := range uc.chainConfigs { + node, err := chainConfig.GetDefaultNode() + if err != nil { + return err + } + // currentHeight, err := node.QueryCurrentHeight() + // if err != nil { + // return err + // } + // TODO: need to make a way to update proposal height + // chainConfig.UpgradePropHeight = currentHeight + int64(chainConfig.VotingPeriod) + int64(config.PropSubmitBlocks) + int64(config.PropBufferBlocks) + chainConfig.UpgradePropHeight = 25 // at least read from the prop plan file + propID := node.TxGovPropSubmitProposal(uc.upgradeJsonFilePath, node.WalletName) + + chainConfig.TxGovVoteFromAllNodes(propID, govv1.VoteOption_VOTE_OPTION_YES) + } + + // wait till all chains halt at upgrade height + for _, chainConfig := range uc.chainConfigs { + uc.t.Logf("waiting to reach upgrade height on chain %s", chainConfig.Id) + chainConfig.WaitUntilHeight(chainConfig.UpgradePropHeight) + uc.t.Logf("upgrade height reached on chain %s", chainConfig.Id) + } + + // remove all containers so we can upgrade them to the new version + for _, chainConfig := range uc.chainConfigs { + for _, validatorConfig := range chainConfig.NodeConfigs { + err := uc.containerManager.RemoveNodeResource(validatorConfig.Name) + if err != nil { + return err + } + } + } + + // remove all containers so we can upgrade them to the new version + for _, chainConfig := range uc.chainConfigs { + if err := uc.upgradeContainers(chainConfig, chainConfig.UpgradePropHeight); err != nil { + return err + } + } + return nil +} + +func (uc *UpgradeConfigurer) runForkUpgrade() { + for _, chainConfig := range uc.chainConfigs { + uc.t.Logf("waiting to reach fork height on chain %s", chainConfig.Id) + chainConfig.WaitUntilHeight(uc.forkHeight) + uc.t.Logf("fork height reached on chain %s", chainConfig.Id) + } +} + +func (uc *UpgradeConfigurer) upgradeContainers(chainConfig *chain.Config, propHeight int64) error { + // upgrade containers to the locally compiled daemon + uc.t.Logf("starting upgrade for chain-id: %s...", chainConfig.Id) + uc.containerManager.CurrentRepository = containers.BabylonContainerName + + errCh := make(chan error, len(chainConfig.NodeConfigs)) + var wg sync.WaitGroup + + for _, node := range chainConfig.NodeConfigs { + wg.Add(1) + go func(node *chain.NodeConfig) { + defer wg.Done() + if err := node.Run(); err != nil { + errCh <- err + } + }(node) + } + + // Wait for all goroutines to complete + wg.Wait() + close(errCh) + + // Check if any of the goroutines returned an error + for err := range errCh { + if err != nil { + return err + } + } + + uc.t.Logf("waiting to upgrade containers on chain %s", chainConfig.Id) + chainConfig.WaitUntilHeight(propHeight + 1) + uc.t.Logf("upgrade successful on chain %s", chainConfig.Id) + return nil +} diff --git a/test/e2e/containers/config.go b/test/e2e/containers/config.go index 964367871..2654c71aa 100644 --- a/test/e2e/containers/config.go +++ b/test/e2e/containers/config.go @@ -3,38 +3,50 @@ package containers // ImageConfig contains all images and their respective tags // needed for running e2e tests. type ImageConfig struct { + // IBC relayer for cosmos-SDK RelayerRepository string RelayerTag string + + CurrentRepository string } //nolint:deadcode const ( - // name of babylon container produced by running `make localnet-build-env` + // name of babylon imge produced by running `make build-docker` BabylonContainerName = "babylonchain/babylond" + // name of babylon image produced by running `make build-docker-e2e` + BabylonContainerNameBeforeUpgrade = "babylonchain/babylond-before-upgrade" + // name of the image produced by running `make e2e-init-chain` in contrib/images + InitChainContainerE2E = "babylonchain/babylond-e2e-init-chain" hermesRelayerRepository = "informalsystems/hermes" hermesRelayerTag = "v1.8.2" // Built using the `build-cosmos-relayer-docker` target on an Intel (amd64) machine and pushed to ECR cosmosRelayerRepository = "public.ecr.aws/t9e9i3h0/cosmos-relayer" // TODO: Replace with version tag once we have a working version - cosmosRelayerTag = "main" + cosmosRelayerTag = "main" ) // NewImageConfig returns ImageConfig needed for running e2e test. // If isUpgrade is true, returns images for running the upgrade // If isFork is true, utilizes provided fork height to initiate fork logic -func NewImageConfig(isCosmosRelayer bool) ImageConfig { +func NewImageConfig(isCosmosRelayer, isUpgrade bool) (ic ImageConfig) { + ic = ImageConfig{ + CurrentRepository: BabylonContainerName, + } + + if isUpgrade { + // starts at the older version and later upgrades it to current branch... BabylonContainerName + ic.CurrentRepository = BabylonContainerNameBeforeUpgrade + } + if isCosmosRelayer { - config := ImageConfig{ - RelayerRepository: cosmosRelayerRepository, - RelayerTag: cosmosRelayerTag, - } - return config + ic.RelayerRepository = cosmosRelayerRepository + ic.RelayerTag = cosmosRelayerTag + return ic } else { - config := ImageConfig{ - RelayerRepository: hermesRelayerRepository, - RelayerTag: hermesRelayerTag, - } - return config + ic.RelayerRepository = hermesRelayerRepository + ic.RelayerTag = hermesRelayerTag + return ic } } diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index 737af78ea..60c9ee485 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -40,9 +40,9 @@ type Manager struct { // NewManager creates a new Manager instance and initializes // all Docker specific utilities. Returns an error if initialization fails. -func NewManager(isDebugLogEnabled bool, isCosmosRelayer bool) (docker *Manager, err error) { +func NewManager(isDebugLogEnabled bool, isCosmosRelayer, isUpgrade bool) (docker *Manager, err error) { docker = &Manager{ - ImageConfig: NewImageConfig(isCosmosRelayer), + ImageConfig: NewImageConfig(isCosmosRelayer, isUpgrade), resources: make(map[string]*dockertest.Resource), isDebugLogEnabled: isDebugLogEnabled, } @@ -253,7 +253,7 @@ func (m *Manager) RunNodeResource(chainId string, containerName, valCondifDir st runOpts := &dockertest.RunOptions{ Name: containerName, - Repository: BabylonContainerName, + Repository: m.CurrentRepository, NetworkID: m.network.Network.ID, User: "root:root", Entrypoint: []string{ @@ -345,3 +345,38 @@ func noRestart(config *docker.HostConfig) { Name: "no", } } + +// RunChainInitResource runs a chain init container to initialize genesis and configs for a chain with chainId. +// The chain is to be configured with chainVotingPeriod and validators deserialized from validatorConfigBytes. +// The genesis and configs are to be mounted on the init container as volume on mountDir path. +// Returns the container resource and error if any. This method does not Purge the container. The caller +// must deal with removing the resource. +func (m *Manager) RunChainInitResource(chainId string, chainVotingPeriod, chainExpeditedVotingPeriod int, validatorConfigBytes []byte, mountDir string, forkHeight int) (*dockertest.Resource, error) { + votingPeriodDuration := time.Duration(chainVotingPeriod * 1000000000) + expeditedVotingPeriodDuration := time.Duration(chainExpeditedVotingPeriod * 1000000000) + + initResource, err := m.pool.RunWithOptions( + &dockertest.RunOptions{ + Name: chainId, + Repository: InitChainContainerE2E, + NetworkID: m.network.Network.ID, + Cmd: []string{ + fmt.Sprintf("--data-dir=%s", mountDir), + fmt.Sprintf("--chain-id=%s", chainId), + fmt.Sprintf("--config=%s", validatorConfigBytes), + fmt.Sprintf("--voting-period=%v", votingPeriodDuration), + fmt.Sprintf("--expedited-voting-period=%v", expeditedVotingPeriodDuration), + fmt.Sprintf("--fork-height=%v", forkHeight), + }, + User: "root:root", + Mounts: []string{ + fmt.Sprintf("%s:%s", mountDir, mountDir), + }, + }, + noRestart, + ) + if err != nil { + return nil, err + } + return initResource, nil +} diff --git a/test/e2e/upgrades/vanilla.json b/test/e2e/upgrades/vanilla.json index c9fd6c9d3..f38550fa1 100644 --- a/test/e2e/upgrades/vanilla.json +++ b/test/e2e/upgrades/vanilla.json @@ -5,7 +5,7 @@ { "@type": "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", "authority": "bbn10d07y265gmmuvt4z0w9aw880jnsr700jduz5f2", - "plan": { "name": "vanilla", "info": "Msg info", "height": 20 } + "plan": { "name": "vanilla", "info": "Msg info", "height": 25 } } ], "deposit": "500000000ubbn", From 2b0d96e08b6e4a3bd2331081eabb8b245854916c Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:05:44 -0300 Subject: [PATCH 18/36] chore: removed unecessary secret key at node level --- test/e2e/btc_staking_e2e_test.go | 15 ++++++++++----- test/e2e/initialization/export.go | 3 --- test/e2e/initialization/node.go | 1 - 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index e76a83c11..ab058bc1d 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -297,11 +297,15 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.Equal(prCommitMap[activatedHeight].Commitment, msgCommitPubRandList.Commitment) // no reward gauge for finality provider and delegation yet - fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) + + fpBabylonAddr, err := sdk.AccAddressFromBech32(nonValidatorNode.PublicAddress) + s.Error(err) + _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) s.Error(err) - delBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) - _, err = nonValidatorNode.QueryRewardGauge(delBabylonAddr) + + delBabylonAddr := fpBabylonAddr + _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) s.Error(err) /* @@ -358,8 +362,9 @@ func (s *BTCStakingTestSuite) Test4WithdrawReward() { s.NoError(err) // finality provider balance before withdraw - fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) - delBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) + fpBabylonAddr, err := sdk.AccAddressFromBech32(nonValidatorNode.PublicAddress) + s.Error(err) + delBabylonAddr := fpBabylonAddr fpBalance, err := nonValidatorNode.QueryBalances(fpBabylonAddr.String()) s.NoError(err) // finality provider reward gauge should not be fully withdrawn diff --git a/test/e2e/initialization/export.go b/test/e2e/initialization/export.go index 663250876..ebe2c2522 100644 --- a/test/e2e/initialization/export.go +++ b/test/e2e/initialization/export.go @@ -2,8 +2,6 @@ package initialization import ( "fmt" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) type ChainMeta struct { @@ -17,7 +15,6 @@ type Node struct { Mnemonic string `json:"mnemonic"` PublicAddress string `json:"publicAddress"` WalletName string `json:"walletName"` - SecretKey cryptotypes.PrivKey PublicKey []byte `json:"publicKey"` PeerId string `json:"peerId"` IsValidator bool `json:"isValidator"` diff --git a/test/e2e/initialization/node.go b/test/e2e/initialization/node.go index d2a8dc1bf..0e940b1a8 100644 --- a/test/e2e/initialization/node.go +++ b/test/e2e/initialization/node.go @@ -248,7 +248,6 @@ func (n *internalNode) export() *Node { Mnemonic: n.mnemonic, PublicAddress: addr.String(), WalletName: n.keyInfo.Name, - SecretKey: n.privateKey, PublicKey: pub.Bytes(), PeerId: n.peerId, IsValidator: n.isValidator, From 35100b282224496ec190d6e0eba9a0257e3e3e45 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:06:29 -0300 Subject: [PATCH 19/36] chore: add checker for vanilla upgrade --- test/e2e/e2e_test.go | 6 +- ...oftware_upgrade_current_branch_e2e_test.go | 85 ------------------- test/e2e/software_upgrade_e2e_test.go | 43 ++++++++++ 3 files changed, 46 insertions(+), 88 deletions(-) delete mode 100644 test/e2e/software_upgrade_current_branch_e2e_test.go create mode 100644 test/e2e/software_upgrade_e2e_test.go diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 0eb9240dd..cc78d6b15 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -36,7 +36,7 @@ func TestBTCStakingTestSuite(t *testing.T) { suite.Run(t, new(BTCStakingTestSuite)) } -// TestSoftwareUpgradeCurrentBranchTestSuite tests software upgrade protocol end-to-end -func TestSoftwareUpgradeCurrentBranchTestSuite(t *testing.T) { - suite.Run(t, new(SoftwareUpgradeCurrentBranchTestSuite)) +// TestSoftwareUpgradeTestSuite tests software upgrade protocol end-to-end +func TestSoftwareUpgradeTestSuite(t *testing.T) { + suite.Run(t, new(SoftwareUpgradeVanillaTestSuite)) } diff --git a/test/e2e/software_upgrade_current_branch_e2e_test.go b/test/e2e/software_upgrade_current_branch_e2e_test.go deleted file mode 100644 index 298285437..000000000 --- a/test/e2e/software_upgrade_current_branch_e2e_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package e2e - -import ( - "fmt" - - govv1 "cosmossdk.io/api/cosmos/gov/v1" - "github.com/stretchr/testify/suite" - - "github.com/babylonchain/babylon/test/e2e/configurer" -) - -const ( - // Mount path in container is fmt.Sprintf("%s/upgrades:/upgrades", pwd) - vanillaUpgradeFilePath = "/upgrades/vanilla.json" -) - -type SoftwareUpgradeCurrentBranchTestSuite struct { - suite.Suite - - configurer configurer.Configurer -} - -func (s *SoftwareUpgradeCurrentBranchTestSuite) SetupSuite() { - s.T().Log("setting up e2e integration test suite...") - var err error - - // The e2e test flow is as follows: - // - // 1. Configure 1 chain with some validator nodes - // 2. Execute various e2e tests - s.configurer, err = configurer.NewSoftwareUpgradeTest(s.T(), true) - s.NoError(err) - err = s.configurer.ConfigureChains() - s.NoError(err) - err = s.configurer.RunSetup() - s.NoError(err) -} - -func (s *SoftwareUpgradeCurrentBranchTestSuite) TearDownSuite() { - err := s.configurer.ClearResources() - s.Require().NoError(err) -} - -// Test1UpgradeVanilla is an end-to-end test for -// running a software upgrade proposal -func (s *SoftwareUpgradeCurrentBranchTestSuite) Test1UpgradeVanilla() { - // chain is already start the chain with software upgrade available - chainA := s.configurer.GetChainConfig(0) - chainA.WaitUntilHeight(1) - - nonValidatorNode, err := chainA.GetNodeAtIndex(2) - s.NoError(err) - - fpsBeforeUpgrade := nonValidatorNode.QueryFinalityProviders() - - // software upgrade gov prop - propID := nonValidatorNode.TxGovPropSubmitProposal(vanillaUpgradeFilePath, nonValidatorNode.WalletName) - s.Equal(1, propID) - - // vote from all nodes - chainA.TxGovVoteFromAllNodes(propID, govv1.VoteOption_VOTE_OPTION_YES) - - tx := nonValidatorNode.QueryProposal(propID) - fmt.Printf("\n prop %+v", tx) - - // waits for block to reach from plan + 1 - // tricky to get current heigth and set it in the json, because the file is - // load at the mounting point of the node it could be created at runtime and - // stored in the filesystem of the container - nonValidatorNode.WaitForBlockHeight(21) - - tx = nonValidatorNode.QueryProposal(propID) - fmt.Printf("\n prop %+v", tx) - - // verifies vanilla upgrade was completed - fpsAfterUpgrade := nonValidatorNode.QueryFinalityProviders() - s.Equal(len(fpsBeforeUpgrade)+1, len(fpsAfterUpgrade)) - - // docker logs -f - // 2:09AM ERR BINARY UPDATED BEFORE TRIGGER! UPGRADE "vanilla" - in binary but not executed on chain. Downgrade your binary module=x/upgrade - // 2:09AM ERR error in proxyAppConn.FinalizeBlock err="BINARY UPDATED BEFORE TRIGGER! UPGRADE \"vanilla\" - in binary but not executed on chain. Downgrade your binary" module=state - tx = nonValidatorNode.QueryProposal(propID) - fmt.Printf("\n prop %+v", tx) - -} diff --git a/test/e2e/software_upgrade_e2e_test.go b/test/e2e/software_upgrade_e2e_test.go new file mode 100644 index 000000000..0fd0812da --- /dev/null +++ b/test/e2e/software_upgrade_e2e_test.go @@ -0,0 +1,43 @@ +package e2e + +import ( + "github.com/stretchr/testify/suite" + + "github.com/babylonchain/babylon/test/e2e/configurer" +) + +type SoftwareUpgradeVanillaTestSuite struct { + suite.Suite + + configurer configurer.Configurer +} + +func (s *SoftwareUpgradeVanillaTestSuite) SetupSuite() { + s.T().Log("setting up e2e integration test suite...") + var err error + + s.configurer, err = configurer.NewSoftwareUpgradeTest(s.T(), false) + s.NoError(err) + err = s.configurer.ConfigureChains() + s.NoError(err) + err = s.configurer.RunSetup() // upgrade happens at the setup of configurer. + s.NoError(err) +} + +func (s *SoftwareUpgradeVanillaTestSuite) TearDownSuite() { + err := s.configurer.ClearResources() + s.Require().NoError(err) +} + +// TestUpgradeVanilla only checks that new fp was added. +func (s *SoftwareUpgradeVanillaTestSuite) TestUpgradeVanilla() { + // chain is already upgraded, only checks for differences in state are expected + chainA := s.configurer.GetChainConfig(0) + chainA.WaitUntilHeight(30) // five blocks more than upgrade + + n, err := chainA.GetDefaultNode() + s.NoError(err) + + fps := n.QueryFinalityProviders() + s.Len(fps, 1, "it should have one finality provider, since the vanilla upgrade just added a new one") +} From cd043dd12d85665790d010d31cf9bca4fec74654 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 23 Jul 2024 23:06:43 -0300 Subject: [PATCH 20/36] chore: add status command --- test/e2e/configurer/chain/node.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/e2e/configurer/chain/node.go b/test/e2e/configurer/chain/node.go index 2a8f1ccd5..cb79fc673 100644 --- a/test/e2e/configurer/chain/node.go +++ b/test/e2e/configurer/chain/node.go @@ -9,6 +9,7 @@ import ( "testing" "time" + cmtjson "github.com/cometbft/cometbft/libs/json" rpchttp "github.com/cometbft/cometbft/rpc/client/http" coretypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/stretchr/testify/require" @@ -192,3 +193,19 @@ func (n *NodeConfig) LogActionF(msg string, args ...interface{}) { s := fmt.Sprintf(msg, args...) n.t.Logf("[%s] %s. From container %s", timeSinceStart, s, n.Name) } + +func (n *NodeConfig) Status() (*coretypes.ResultStatus, error) { + cmd := []string{"babylond", "status", "--output=json"} + outBuf, _, err := n.containerManager.ExecCmd(n.t, n.Name, cmd, "") + if err != nil { + return nil, err + } + + var r coretypes.ResultStatus + err = cmtjson.Unmarshal(outBuf.Bytes(), &r) + if err != nil { + return nil, err + } + + return &r, nil +} From 454ae6e84cdffd5d01d62edcc3a0166386898013 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 08:30:45 -0300 Subject: [PATCH 21/36] chore: wait to purge resources than remove network --- test/e2e/containers/containers.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index 60c9ee485..2de3bc413 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -332,11 +332,11 @@ func (m *Manager) ClearResources() (e error) { }) } - g.Go(func() error { - return m.pool.RemoveNetwork(m.network) - }) + if err := g.Wait(); err != nil { + return err + } - return g.Wait() + return m.pool.RemoveNetwork(m.network) } func noRestart(config *docker.HostConfig) { From 58990049cc8f4ca7263e4ba8d27ff5908ecf9079 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 08:37:48 -0300 Subject: [PATCH 22/36] feat: add bank multisend --- test/e2e/configurer/chain/commands.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index bb789ec4b..0b8b274ae 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -95,6 +95,10 @@ func (n *NodeConfig) BankSendFromNode(receiveAddress, amount string) { n.BankSend(n.WalletName, receiveAddress, amount) } +func (n *NodeConfig) BankMultiSendFromNode(addresses []string, amount string) { + n.BankMultiSend(n.WalletName, addresses, amount) +} + func (n *NodeConfig) BankSend(fromWallet, to, amount string, overallFlags ...string) { fromAddr := n.GetWallet(fromWallet) n.LogActionF("bank sending %s from wallet %s to %s", amount, fromWallet, to) @@ -104,6 +108,16 @@ func (n *NodeConfig) BankSend(fromWallet, to, amount string, overallFlags ...str n.LogActionF("successfully sent bank sent %s from address %s to %s", amount, fromWallet, to) } +func (n *NodeConfig) BankMultiSend(fromWallet string, to []string, amount string, overallFlags ...string) { + fromAddr := n.GetWallet(fromWallet) + toFormated := strings.Join(to, " ") + n.LogActionF("bank multi-send sending %s from wallet %s to %s", amount, fromWallet, toFormated) + cmd := []string{"babylond", "tx", "bank", "multi-send", fromAddr, toFormated, amount, fmt.Sprintf("--from=%s", fromWallet)} + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) + require.NoError(n.t, err) + n.LogActionF("successfully sent bank multi-send %s from address %s to %s", amount, fromWallet, toFormated) +} + func (n *NodeConfig) BankSendOutput(fromWallet, to, amount string, overallFlags ...string) (out bytes.Buffer, errBuff bytes.Buffer, err error) { fromAddr := n.GetWallet(fromWallet) n.LogActionF("bank sending %s from wallet %s to %s", amount, fromWallet, to) From ccc91c938087b0a60b9eff0729ec757086286bb4 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 08:38:05 -0300 Subject: [PATCH 23/36] fix: use multisend to avoid sequence error --- test/e2e/configurer/upgrade.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/e2e/configurer/upgrade.go b/test/e2e/configurer/upgrade.go index ba3080614..48fa2355a 100644 --- a/test/e2e/configurer/upgrade.go +++ b/test/e2e/configurer/upgrade.go @@ -134,10 +134,15 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { amountToSend := sdk.NewCoin(appparams.BaseCoinUnit, sdkmath.NewInt(1000000)) // 1bbn for _, chain := range uc.chainConfigs { firstNode := chain.NodeConfigs[0] - for i := 1; i < len(chain.NodeConfigs); i++ { + otherNodes := chain.NodeConfigs[:1] + // first node to others... + + addresses := make([]string, len(otherNodes)) + for i := 1; i < len(otherNodes); i++ { nodeI := chain.NodeConfigs[i] - firstNode.BankSendFromNode(nodeI.PublicAddress, amountToSend.String()) + addresses[i] = nodeI.PublicAddress } + firstNode.BankMultiSendFromNode(addresses, amountToSend.String()) } return nil From 25195cb27276aa59538d91ef558e34a1c648396b Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 09:41:26 -0300 Subject: [PATCH 24/36] fix: usage and command bank multisend --- test/e2e/configurer/chain/commands.go | 17 ++++++++++++----- test/e2e/configurer/upgrade.go | 9 ++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 0b8b274ae..f49e4d77c 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -108,14 +108,21 @@ func (n *NodeConfig) BankSend(fromWallet, to, amount string, overallFlags ...str n.LogActionF("successfully sent bank sent %s from address %s to %s", amount, fromWallet, to) } -func (n *NodeConfig) BankMultiSend(fromWallet string, to []string, amount string, overallFlags ...string) { +func (n *NodeConfig) BankMultiSend(fromWallet string, receivers []string, amount string, overallFlags ...string) { + if len(receivers) == 0 { + require.Error(n.t, fmt.Errorf("no address to send to")) + } + fromAddr := n.GetWallet(fromWallet) - toFormated := strings.Join(to, " ") - n.LogActionF("bank multi-send sending %s from wallet %s to %s", amount, fromWallet, toFormated) - cmd := []string{"babylond", "tx", "bank", "multi-send", fromAddr, toFormated, amount, fmt.Sprintf("--from=%s", fromWallet)} + n.LogActionF("bank multi-send sending %s from wallet %s to %+v", amount, fromWallet, receivers) + + cmd := []string{"babylond", "tx", "bank", "multi-send", fromAddr} // starts the initial flags + cmd = append(cmd, receivers...) // appends all the receivers + cmd = append(cmd, amount, fmt.Sprintf("--from=%s", fromWallet)) // set amounts and overall + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) require.NoError(n.t, err) - n.LogActionF("successfully sent bank multi-send %s from address %s to %s", amount, fromWallet, toFormated) + n.LogActionF("successfully sent bank multi-send %s from address %s to %+v", amount, fromWallet, receivers) } func (n *NodeConfig) BankSendOutput(fromWallet, to, amount string, overallFlags ...string) (out bytes.Buffer, errBuff bytes.Buffer, err error) { diff --git a/test/e2e/configurer/upgrade.go b/test/e2e/configurer/upgrade.go index 48fa2355a..8c4e60e0d 100644 --- a/test/e2e/configurer/upgrade.go +++ b/test/e2e/configurer/upgrade.go @@ -134,13 +134,12 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { amountToSend := sdk.NewCoin(appparams.BaseCoinUnit, sdkmath.NewInt(1000000)) // 1bbn for _, chain := range uc.chainConfigs { firstNode := chain.NodeConfigs[0] - otherNodes := chain.NodeConfigs[:1] - // first node to others... + otherNodes := chain.NodeConfigs[1:] + // first node send to others... addresses := make([]string, len(otherNodes)) - for i := 1; i < len(otherNodes); i++ { - nodeI := chain.NodeConfigs[i] - addresses[i] = nodeI.PublicAddress + for i, node := range otherNodes { + addresses[i] = node.PublicAddress } firstNode.BankMultiSendFromNode(addresses, amountToSend.String()) } From 36a86a4f6ad32f52dd9d65e5d989fecd00693543 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 10:26:33 -0300 Subject: [PATCH 25/36] fix: fp babylon address --- test/e2e/btc_staking_e2e_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index ab058bc1d..43de54161 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -298,15 +298,12 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat // no reward gauge for finality provider and delegation yet - fpBabylonAddr, err := sdk.AccAddressFromBech32(nonValidatorNode.PublicAddress) + fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr) s.Error(err) _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) s.Error(err) - delBabylonAddr := fpBabylonAddr - _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) - s.Error(err) /* submit finality signature @@ -362,9 +359,10 @@ func (s *BTCStakingTestSuite) Test4WithdrawReward() { s.NoError(err) // finality provider balance before withdraw - fpBabylonAddr, err := sdk.AccAddressFromBech32(nonValidatorNode.PublicAddress) + fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr) s.Error(err) delBabylonAddr := fpBabylonAddr + fpBalance, err := nonValidatorNode.QueryBalances(fpBabylonAddr.String()) s.NoError(err) // finality provider reward gauge should not be fully withdrawn From 9f2204700c0d52bf2e78bd4bf328e600d31e8057 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 10:53:50 -0300 Subject: [PATCH 26/36] fix: no error required --- test/e2e/btc_staking_e2e_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 43de54161..802ec2a3d 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -299,10 +299,10 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat // no reward gauge for finality provider and delegation yet fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr) - s.Error(err) + s.NoError(err) _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) - s.Error(err) + s.NoError(err) delBabylonAddr := fpBabylonAddr /* @@ -360,7 +360,7 @@ func (s *BTCStakingTestSuite) Test4WithdrawReward() { // finality provider balance before withdraw fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr) - s.Error(err) + s.NoError(err) delBabylonAddr := fpBabylonAddr fpBalance, err := nonValidatorNode.QueryBalances(fpBabylonAddr.String()) From bcd4e320d82b3a2c6afa156247011daa157ff374 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 11:19:52 -0300 Subject: [PATCH 27/36] fix: add typed error that reward gauge was not found for that addr --- test/e2e/btc_staking_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 802ec2a3d..cb40b3dc7 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -302,7 +302,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.NoError(err) _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) - s.NoError(err) + s.ErrorIs(err, itypes.ErrRewardGaugeNotFound) delBabylonAddr := fpBabylonAddr /* From 0f98f1dc100815b6a71b63d308b8d6f2d35cfa76 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 11:53:28 -0300 Subject: [PATCH 28/36] chore: update error not exactly the same --- test/e2e/btc_staking_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index cb40b3dc7..530aa0d06 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -302,7 +302,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.NoError(err) _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) - s.ErrorIs(err, itypes.ErrRewardGaugeNotFound) + s.ErrorContains(err, itypes.ErrRewardGaugeNotFound.Error()) delBabylonAddr := fpBabylonAddr /* From 285c6070cb304c7ed6dd2d7a4042ee3d13462b9d Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 12:11:43 -0300 Subject: [PATCH 29/36] chore: set linter timeout to 10min --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 085fe6388..a4f1e66b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -77,7 +77,7 @@ jobs: name: Lint command: | curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.55.2 - ./bin/golangci-lint run + ./bin/golangci-lint run --timeout 10m0s build_docker: machine: From 3e629c5e13c5d12ff607d3dfd6738c6be493c74a Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Wed, 24 Jul 2024 22:33:10 -0300 Subject: [PATCH 30/36] chore: cleanup --- Makefile | 2 +- .../images/e2e-initialization/init.Dockerfile | 3 --- test/e2e/configurer/chain/node.go | 7 ------- test/e2e/configurer/config/constants.go | 3 --- test/e2e/configurer/factory.go | 17 ----------------- test/e2e/containers/config.go | 3 ++- 6 files changed, 3 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 0d2b6ffce..182ec1eb1 100644 --- a/Makefile +++ b/Makefile @@ -202,7 +202,7 @@ build-docs: diagrams .PHONY: build-docs ############################################################################### -### Tests & Simulation ### +### E2E build ### ############################################################################### # Executed to build the binary for chain initialization, one of diff --git a/contrib/images/e2e-initialization/init.Dockerfile b/contrib/images/e2e-initialization/init.Dockerfile index a929bf706..0b3095d90 100644 --- a/contrib/images/e2e-initialization/init.Dockerfile +++ b/contrib/images/e2e-initialization/init.Dockerfile @@ -38,9 +38,6 @@ ARG E2E_SCRIPT_NAME COPY --from=build-env /go/src/github.com/babylonchain/babylon/build/${E2E_SCRIPT_NAME} /bin/${E2E_SCRIPT_NAME} -ENV HOME /babylond -WORKDIR $HOME - # Docker ARGs are not expanded in ENTRYPOINT in the exec mode. At the same time, # it is impossible to add CMD arguments when running a container in the shell mode. # As a workaround, we create the entrypoint.sh script to bypass these issues. diff --git a/test/e2e/configurer/chain/node.go b/test/e2e/configurer/chain/node.go index cb79fc673..db6f2cbac 100644 --- a/test/e2e/configurer/chain/node.go +++ b/test/e2e/configurer/chain/node.go @@ -154,13 +154,6 @@ func (n *NodeConfig) WaitForNextBlocks(numberOfBlocks uint64) { }, fmt.Sprintf("Timed out waiting for block %d. Current height is: %d", latest, blockToWait)) } -func (n *NodeConfig) WaitForBlockHeight(blkHeight uint64) { - n.WaitForCondition(func() bool { - newLatest := n.LatestBlockNumber() - return newLatest > blkHeight - }, fmt.Sprintf("Timed out waiting for block %d.", blkHeight)) -} - func (n *NodeConfig) extractOperatorAddressIfValidator() error { if !n.IsValidator { n.t.Logf("node (%s) is not a validator, skipping", n.Name) diff --git a/test/e2e/configurer/config/constants.go b/test/e2e/configurer/config/constants.go index 9ba3a0a09..72ee9e9b4 100644 --- a/test/e2e/configurer/config/constants.go +++ b/test/e2e/configurer/config/constants.go @@ -15,9 +15,6 @@ const ( MaxRetries = 60 // PropSubmitBlocks estimated number of blocks it takes to submit for a proposal PropSubmitBlocks float32 = 1 - // Minimum deposit value for a proposal to enter a voting period. - MinDepositValue = 1000000 - // VanillaUpgradeFilePath upgrade vanilla testing VanillaUpgradeFilePath = "/upgrades/vanilla.json" ) diff --git a/test/e2e/configurer/factory.go b/test/e2e/configurer/factory.go index c9aa4eb9b..0c4d7ca48 100644 --- a/test/e2e/configurer/factory.go +++ b/test/e2e/configurer/factory.go @@ -197,23 +197,6 @@ func NewBTCStakingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, ), nil } -// NewSoftwareUpgradeCurrentBranchTest returns a new Configurer for Software Upgrade testing -func NewSoftwareUpgradeCurrentBranchTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { - containerManager, err := containers.NewManager(isDebugLogEnabled, false, false) - if err != nil { - return nil, err - } - - return NewCurrentBranchConfigurer(t, - []*chain.Config{ - // we only need 1 chain for testing upgrade - chain.New(t, containerManager, initialization.ChainAID, validatorConfigsChainA, nil), - }, - baseSetup, // base set up - containerManager, - ), nil -} - // NewSoftwareUpgradeTest returns a new Configurer for Software Upgrade testing func NewSoftwareUpgradeTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { containerManager, err := containers.NewManager(isDebugLogEnabled, false, true) diff --git a/test/e2e/containers/config.go b/test/e2e/containers/config.go index 2654c71aa..0c6058ff2 100644 --- a/test/e2e/containers/config.go +++ b/test/e2e/containers/config.go @@ -12,7 +12,8 @@ type ImageConfig struct { //nolint:deadcode const ( - // name of babylon imge produced by running `make build-docker` + // Images that do not have specified tag, latest will be used by default. + // name of babylon image produced by running `make build-docker` BabylonContainerName = "babylonchain/babylond" // name of babylon image produced by running `make build-docker-e2e` BabylonContainerNameBeforeUpgrade = "babylonchain/babylond-before-upgrade" From 5019776be387c39361d1d9fc16bba5b5d33d392a Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Thu, 25 Jul 2024 08:50:50 -0300 Subject: [PATCH 31/36] fix: used parameter of voting period to update gov genesis --- test/e2e/initialization/config.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index 9af54728e..f0adbbbd4 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -218,7 +218,7 @@ func initGenesis(chain *internalChain, votingPeriod, expeditedVotingPeriod time. return err } - err = updateModuleGenesis(appGenState, govtypes.ModuleName, &govv1.GenesisState{}, updateGovGenesis) + err = updateModuleGenesis(appGenState, govtypes.ModuleName, &govv1.GenesisState{}, updateGovGenesis(votingPeriod, expeditedVotingPeriod)) if err != nil { return err } @@ -295,11 +295,12 @@ func updateBankGenesis(bankGenState *banktypes.GenesisState) { }) } -func updateGovGenesis(govGenState *govv1.GenesisState) { - govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(BabylonDenom, sdkmath.NewInt(100))) - - votingPeriod := time.Duration(time.Second * 10) - govGenState.Params.VotingPeriod = &votingPeriod +func updateGovGenesis(votingPeriod, expeditedVotingPeriod time.Duration) func(govGenState *govv1.GenesisState) { + return func(govGenState *govv1.GenesisState) { + govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(BabylonDenom, sdkmath.NewInt(100))) + govGenState.Params.VotingPeriod = &votingPeriod + govGenState.Params.ExpeditedVotingPeriod = &expeditedVotingPeriod + } } func updateMintGenesis(mintGenState *minttypes.GenesisState) { From ff6532a07cee972ceff48322cb4d488dc6f1b195 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Thu, 25 Jul 2024 08:51:47 -0300 Subject: [PATCH 32/36] chore: rename from NewSoftwareUpgradeTest to NewSoftwareUpgradeConfigurer --- test/e2e/configurer/factory.go | 4 ++-- test/e2e/software_upgrade_e2e_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/configurer/factory.go b/test/e2e/configurer/factory.go index 0c4d7ca48..b9823e171 100644 --- a/test/e2e/configurer/factory.go +++ b/test/e2e/configurer/factory.go @@ -197,8 +197,8 @@ func NewBTCStakingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, ), nil } -// NewSoftwareUpgradeTest returns a new Configurer for Software Upgrade testing -func NewSoftwareUpgradeTest(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { +// NewSoftwareUpgradeConfigurer returns a new Configurer for Software Upgrade testing +func NewSoftwareUpgradeConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { containerManager, err := containers.NewManager(isDebugLogEnabled, false, true) if err != nil { return nil, err diff --git a/test/e2e/software_upgrade_e2e_test.go b/test/e2e/software_upgrade_e2e_test.go index 0fd0812da..edf06827a 100644 --- a/test/e2e/software_upgrade_e2e_test.go +++ b/test/e2e/software_upgrade_e2e_test.go @@ -16,7 +16,7 @@ func (s *SoftwareUpgradeVanillaTestSuite) SetupSuite() { s.T().Log("setting up e2e integration test suite...") var err error - s.configurer, err = configurer.NewSoftwareUpgradeTest(s.T(), false) + s.configurer, err = configurer.NewSoftwareUpgradeConfigurer(s.T(), false) s.NoError(err) err = s.configurer.ConfigureChains() s.NoError(err) From 0a16ccb904a0678a7ec196f6740d609ab40fb57a Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Thu, 25 Jul 2024 14:51:47 -0300 Subject: [PATCH 33/36] chore: add check for applied plan by verifying the height in which it was executed --- test/e2e/configurer/chain/queries.go | 13 +++++++++++++ test/e2e/software_upgrade_e2e_test.go | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index f7b2c9cb5..ebf694c58 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -12,6 +12,7 @@ import ( "time" sdkmath "cosmossdk.io/math" + upgradetypes "cosmossdk.io/x/upgrade/types" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" cmtabcitypes "github.com/cometbft/cometbft/abci/types" cmttypes "github.com/cometbft/cometbft/types" @@ -430,6 +431,18 @@ func (n *NodeConfig) QueryProposals() govtypesv1.QueryProposalsResponse { return resp } +func (n *NodeConfig) QueryAppliedPlan(planName string) upgradetypes.QueryAppliedPlanResponse { + path := fmt.Sprintf("cosmos/upgrade/v1beta1/applied_plan/%s", planName) + bz, err := n.QueryGRPCGateway(path, url.Values{}) + require.NoError(n.t, err) + + var resp upgradetypes.QueryAppliedPlanResponse + err = util.Cdc.UnmarshalJSON(bz, &resp) + require.NoError(n.t, err) + + return resp +} + func (n *NodeConfig) QueryWasmSmartObject(contract string, msg string) (resultObject map[string]interface{}, err error) { err = n.QueryWasmSmart(contract, msg, &resultObject) if err != nil { diff --git a/test/e2e/software_upgrade_e2e_test.go b/test/e2e/software_upgrade_e2e_test.go index edf06827a..61a9f252d 100644 --- a/test/e2e/software_upgrade_e2e_test.go +++ b/test/e2e/software_upgrade_e2e_test.go @@ -38,6 +38,10 @@ func (s *SoftwareUpgradeVanillaTestSuite) TestUpgradeVanilla() { n, err := chainA.GetDefaultNode() s.NoError(err) + // makes sure that the upgrade was acutally executed + resp := n.QueryAppliedPlan("vanilla") + s.Equal(25, resp.Height, "the plan should be applied at the height 25") + fps := n.QueryFinalityProviders() s.Len(fps, 1, "it should have one finality provider, since the vanilla upgrade just added a new one") } From a3a3d6ecfa181ab581844a718765c888c285ae85 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Thu, 25 Jul 2024 14:59:53 -0300 Subject: [PATCH 34/36] chore: add upgrade path as parameter in configurer --- test/e2e/configurer/factory.go | 5 ++--- test/e2e/software_upgrade_e2e_test.go | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/configurer/factory.go b/test/e2e/configurer/factory.go index b9823e171..a33b0be34 100644 --- a/test/e2e/configurer/factory.go +++ b/test/e2e/configurer/factory.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/babylonchain/babylon/test/e2e/configurer/chain" - "github.com/babylonchain/babylon/test/e2e/configurer/config" "github.com/babylonchain/babylon/test/e2e/containers" "github.com/babylonchain/babylon/test/e2e/initialization" zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" @@ -198,7 +197,7 @@ func NewBTCStakingConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, } // NewSoftwareUpgradeConfigurer returns a new Configurer for Software Upgrade testing -func NewSoftwareUpgradeConfigurer(t *testing.T, isDebugLogEnabled bool) (Configurer, error) { +func NewSoftwareUpgradeConfigurer(t *testing.T, isDebugLogEnabled bool, upgradePath string) (Configurer, error) { containerManager, err := containers.NewManager(isDebugLogEnabled, false, true) if err != nil { return nil, err @@ -211,7 +210,7 @@ func NewSoftwareUpgradeConfigurer(t *testing.T, isDebugLogEnabled bool) (Configu }, withUpgrade(baseSetup), // base set up with upgrade containerManager, - config.VanillaUpgradeFilePath, + upgradePath, 0, ), nil } diff --git a/test/e2e/software_upgrade_e2e_test.go b/test/e2e/software_upgrade_e2e_test.go index 61a9f252d..e8ede1e43 100644 --- a/test/e2e/software_upgrade_e2e_test.go +++ b/test/e2e/software_upgrade_e2e_test.go @@ -4,6 +4,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/babylonchain/babylon/test/e2e/configurer" + "github.com/babylonchain/babylon/test/e2e/configurer/config" ) type SoftwareUpgradeVanillaTestSuite struct { @@ -16,7 +17,7 @@ func (s *SoftwareUpgradeVanillaTestSuite) SetupSuite() { s.T().Log("setting up e2e integration test suite...") var err error - s.configurer, err = configurer.NewSoftwareUpgradeConfigurer(s.T(), false) + s.configurer, err = configurer.NewSoftwareUpgradeConfigurer(s.T(), false, config.VanillaUpgradeFilePath) s.NoError(err) err = s.configurer.ConfigureChains() s.NoError(err) From 9d9ab6873e42acf36ef5f36215e8ba3d90ea6977 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Thu, 25 Jul 2024 21:57:50 -0300 Subject: [PATCH 35/36] fix: set type of expected height to match equal value --- test/e2e/software_upgrade_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/software_upgrade_e2e_test.go b/test/e2e/software_upgrade_e2e_test.go index e8ede1e43..c5fa87c82 100644 --- a/test/e2e/software_upgrade_e2e_test.go +++ b/test/e2e/software_upgrade_e2e_test.go @@ -41,7 +41,7 @@ func (s *SoftwareUpgradeVanillaTestSuite) TestUpgradeVanilla() { // makes sure that the upgrade was acutally executed resp := n.QueryAppliedPlan("vanilla") - s.Equal(25, resp.Height, "the plan should be applied at the height 25") + s.EqualValues(int64(25), resp.Height, "the plan should be applied at the height 25") fps := n.QueryFinalityProviders() s.Len(fps, 1, "it should have one finality provider, since the vanilla upgrade just added a new one") From df5cac90cfb7cf2e28ef2681ddcd3a25cc9a2a19 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Fri, 26 Jul 2024 11:29:00 -0300 Subject: [PATCH 36/36] chore: address PR comments --- contrib/images/Makefile | 3 ++- contrib/images/babylond/Dockerfile | 4 ---- test/e2e/software_upgrade_e2e_test.go | 6 ++++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/contrib/images/Makefile b/contrib/images/Makefile index 7ca6df2dc..b4aaf7467 100644 --- a/contrib/images/Makefile +++ b/contrib/images/Makefile @@ -1,5 +1,6 @@ RELAYER_TAG := $(shell grep '^ENV RELAYER_TAG' cosmos-relayer/Dockerfile | cut -f3 -d\ ) BABYLON_FULL_PATH := $(shell git rev-parse --show-toplevel) +BABYLON_VERSION_BEFORE_UPGRADE ?= a33a3344bb44bde2f3374d3cbf919abb942c341a all: babylond cosmos-relayer @@ -9,7 +10,7 @@ babylond: babylond-rmi babylond-before-upgrade: docker rmi babylonchain/babylond-before-upgrade 2>/dev/null; true && \ docker build --tag babylonchain/babylond-before-upgrade -f babylond/Dockerfile \ - --build-arg VERSION="a33a3344bb44bde2f3374d3cbf919abb942c341a" ${BABYLON_FULL_PATH} + --build-arg VERSION="${BABYLON_VERSION_BEFORE_UPGRADE}" ${BABYLON_FULL_PATH} babylond-rmi: docker rmi babylonchain/babylond 2>/dev/null; true diff --git a/contrib/images/babylond/Dockerfile b/contrib/images/babylond/Dockerfile index 326d5fa7b..6759346c8 100644 --- a/contrib/images/babylond/Dockerfile +++ b/contrib/images/babylond/Dockerfile @@ -1,9 +1,5 @@ FROM golang:1.21 AS build-env -# Customize to your build env - -# TARGETPLATFORM should be one of linux/amd64 or linux/arm64. -ARG TARGETPLATFORM="linux/amd64" # Version to build. Default is empty ARG VERSION diff --git a/test/e2e/software_upgrade_e2e_test.go b/test/e2e/software_upgrade_e2e_test.go index c5fa87c82..d1baf0692 100644 --- a/test/e2e/software_upgrade_e2e_test.go +++ b/test/e2e/software_upgrade_e2e_test.go @@ -39,9 +39,11 @@ func (s *SoftwareUpgradeVanillaTestSuite) TestUpgradeVanilla() { n, err := chainA.GetDefaultNode() s.NoError(err) - // makes sure that the upgrade was acutally executed + expectedUpgradeHeight := int64(25) + + // makes sure that the upgrade was actually executed resp := n.QueryAppliedPlan("vanilla") - s.EqualValues(int64(25), resp.Height, "the plan should be applied at the height 25") + s.EqualValues(expectedUpgradeHeight, resp.Height, "the plan should be applied at the height 25") fps := n.QueryFinalityProviders() s.Len(fps, 1, "it should have one finality provider, since the vanilla upgrade just added a new one")