From 74d6db22e34b838c6d1b6fb88879e21bdf9975d8 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 16:55:32 -0600 Subject: [PATCH 01/18] axelarcork integration test stub --- .github/workflows/integration-tests.yml | 1 + Makefile | 3 + integration_tests/axelar_cork_test.go | 85 +++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 integration_tests/axelar_cork_test.go diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 3cd9abaf..2a2f44d6 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -121,6 +121,7 @@ jobs: matrix: test_type: [ "ScheduledCork", + "AxelarCork", "Auction", "CellarFees", "Incentives", diff --git a/Makefile b/Makefile index 5720b6df..182d3a7a 100644 --- a/Makefile +++ b/Makefile @@ -368,6 +368,9 @@ e2e_basic: e2e_clean_slate e2e_scheduled_cork_test: e2e_clean_slate @E2E_SKIP_CLEANUP=true integration_tests/integration_tests.test -test.failfast -test.v -test.run IntegrationTestSuite -testify.m TestScheduledCork || make -s fail +e2e_axelar_cork_test: e2e_clean_slate + @E2E_SKIP_CLEANUP=true integration_tests/integration_tests.test -test.failfast -test.v -test.run IntegrationTestSuite -testify.m TestAxelarCork || make -s fail + e2e_auction_module_test: e2e_clean_slate @E2E_SKIP_CLEANUP=true integration_tests/integration_tests.test -test.failfast -test.v -test.run IntegrationTestSuite -testify.m TestAuction || make -s fail diff --git a/integration_tests/axelar_cork_test.go b/integration_tests/axelar_cork_test.go new file mode 100644 index 00000000..b10a554b --- /dev/null +++ b/integration_tests/axelar_cork_test.go @@ -0,0 +1,85 @@ +package integration_tests + +import ( + "context" + "time" + + "github.com/cosmos/cosmos-sdk/client" + govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" +) + +func (s *IntegrationTestSuite) TestAxelarCork() { + s.Run("Test the axelarcork module", func() { + // Set up validator, orchestrator, proposer, query client + /* + val0 := s.chain.validators[0] + val0kb, err := val0.keyring() + s.Require().NoError(err) + val0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", &val0kb, "val", val0.address()) + s.Require().NoError(err) + + orch0 := s.chain.orchestrators[0] + orch0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch0.keyring, "orch", orch0.address()) + s.Require().NoError(err) + orch1 := s.chain.orchestrators[1] + orch1ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch1.keyring, "orch", orch1.address()) + s.Require().NoError(err) + + proposer := s.chain.proposer + proposerCtx, err := s.chain.clientContext("tcp://localhost:26657", proposer.keyring, "proposer", proposer.address()) + s.Require().NoError(err) + propID := uint64(1) + + axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) + */ + + //////////////// + // Happy path // + //////////////// + + }) +} + +func (s *IntegrationTestSuite) submitAndVoteForAxelarProposal(proposerCtx *client.Context, orchClientCtx *client.Context, propID uint64, proposalMsg *govtypesv1beta1.MsgSubmitProposal) { + s.T().Log("Submit proposal") + submitProposalResponse, err := s.chain.sendMsgs(*proposerCtx, proposalMsg) + s.Require().NoError(err) + s.Require().Zero(submitProposalResponse.Code, "raw log: %s", submitProposalResponse.RawLog) + + s.T().Log("Check proposal was submitted correctly") + govQueryClient := govtypesv1beta1.NewQueryClient(orchClientCtx) + + s.Require().Eventually(func() bool { + proposalsQueryResponse, err := govQueryClient.Proposals(context.Background(), &govtypesv1beta1.QueryProposalsRequest{}) + if err != nil { + s.T().Logf("error querying proposals: %e", err) + return false + } + + s.Require().NotEmpty(proposalsQueryResponse.Proposals) + s.Require().Equal(propID, proposalsQueryResponse.Proposals[propID-1].ProposalId, "not proposal id %d", propID) + s.Require().Equal(govtypesv1beta1.StatusVotingPeriod, proposalsQueryResponse.Proposals[propID-1].Status, "proposal not in voting period") + + return true + }, time.Second*30, time.Second*5, "proposal submission was never found") + + s.T().Log("Vote for proposal") + for _, val := range s.chain.validators { + kr, err := val.keyring() + s.Require().NoError(err) + localClientCtx, err := s.chain.clientContext("tcp://localhost:26657", &kr, "val", val.address()) + s.Require().NoError(err) + + voteMsg := govtypesv1beta1.NewMsgVote(val.address(), propID, govtypesv1beta1.OptionYes) + voteResponse, err := s.chain.sendMsgs(*localClientCtx, voteMsg) + s.Require().NoError(err) + s.Require().Zero(voteResponse.Code, "Vote error: %s", voteResponse.RawLog) + } + + s.T().Log("Waiting for proposal to be approved") + s.Require().Eventually(func() bool { + proposalQueryResponse, _ := govQueryClient.Proposal(context.Background(), &govtypesv1beta1.QueryProposalRequest{ProposalId: propID}) + return govtypesv1beta1.StatusPassed == proposalQueryResponse.Proposal.Status + }, time.Second*30, time.Second*5, "proposal was never accepted") + s.T().Log("Proposal approved!") +} From 275bea25882cefaa31e7f9c0fdc6e8c0442c4dbd Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 18:51:18 -0600 Subject: [PATCH 02/18] add axelarcork genesis state to integration tests --- ...{axelar_cork_test.go => axelarcork_test.go} | 9 +++++++++ integration_tests/setup_test.go | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) rename integration_tests/{axelar_cork_test.go => axelarcork_test.go} (93%) diff --git a/integration_tests/axelar_cork_test.go b/integration_tests/axelarcork_test.go similarity index 93% rename from integration_tests/axelar_cork_test.go rename to integration_tests/axelarcork_test.go index b10a554b..e43bce52 100644 --- a/integration_tests/axelar_cork_test.go +++ b/integration_tests/axelarcork_test.go @@ -37,6 +37,15 @@ func (s *IntegrationTestSuite) TestAxelarCork() { // Happy path // //////////////// + // add chain configuration + // add managed cellar + // schedule a normal cork + // scheduled cork proposal + // remove managed cellar + // upgrade proxy proposal + // upgrade but then cancel proxy proposal + // remove chain configuration + }) } diff --git a/integration_tests/setup_test.go b/integration_tests/setup_test.go index 0c31bb02..455b2a40 100644 --- a/integration_tests/setup_test.go +++ b/integration_tests/setup_test.go @@ -19,6 +19,7 @@ import ( govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/peggyjv/sommelier/v7/app/params" auctiontypes "github.com/peggyjv/sommelier/v7/x/auction/types" + axelarcorktypes "github.com/peggyjv/sommelier/v7/x/axelarcork/types" cellarfeestypes "github.com/peggyjv/sommelier/v7/x/cellarfees/types" corktypes "github.com/peggyjv/sommelier/v7/x/cork/types" @@ -36,6 +37,7 @@ import ( genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types" "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" "github.com/spf13/viper" @@ -407,11 +409,25 @@ func (s *IntegrationTestSuite) initGenesis() { FundingModuleAccount: cellarfeestypes.ModuleName, ProceedsModuleAccount: cellarfeestypes.ModuleName, }) - bz, err = cdc.MarshalJSON(&auctionGenState) s.Require().NoError(err) appGenState[auctiontypes.ModuleName] = bz + axelarcorkGenState := axelarcorktypes.DefaultGenesisState() + s.Require().NoError(cdc.UnmarshalJSON(appGenState[axelarcorktypes.ModuleName], &axelarcorkGenState)) + axelarcorkGenState.Params = &axelarcorktypes.Params{ + Enabled: true, + IbcChannel: "channel-1", + IbcPort: ibctransfertypes.PortID, + GmpAccount: "axelar1dv4u5k73pzqrxlzujxg3qp8kvc3pje7jtdvu72npnt5zhq05ejcsn5qme5", + ExecutorAccount: "axelar1zl3rxpp70lmte2xr6c4lgske2fyuj3hupcsvcd", + TimeoutDuration: uint64(6 * time.Hour), + CorkTimeoutBlocks: 5000, + } + bz, err = cdc.MarshalJSON(&axelarcorkGenState) + s.Require().NoError(err) + appGenState[axelarcorktypes.ModuleName] = bz + // set cellarfees gen state cellarfeesGenState := cellarfeestypes.DefaultGenesisState() s.Require().NoError(cdc.UnmarshalJSON(appGenState[cellarfeestypes.ModuleName], &cellarfeesGenState)) From c2ebf1684863e7b4e24436a0a413b209e9321f87 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 19:33:12 -0600 Subject: [PATCH 03/18] WIP on axelar integration test --- Makefile | 4 +- integration_tests/axelarcork_test.go | 89 +++++++++++++++++++++------- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 182d3a7a..ac37a1d0 100644 --- a/Makefile +++ b/Makefile @@ -368,10 +368,10 @@ e2e_basic: e2e_clean_slate e2e_scheduled_cork_test: e2e_clean_slate @E2E_SKIP_CLEANUP=true integration_tests/integration_tests.test -test.failfast -test.v -test.run IntegrationTestSuite -testify.m TestScheduledCork || make -s fail -e2e_axelar_cork_test: e2e_clean_slate +e2e_axelarcork_test: e2e_clean_slate @E2E_SKIP_CLEANUP=true integration_tests/integration_tests.test -test.failfast -test.v -test.run IntegrationTestSuite -testify.m TestAxelarCork || make -s fail -e2e_auction_module_test: e2e_clean_slate +e2e_auction_test: e2e_clean_slate @E2E_SKIP_CLEANUP=true integration_tests/integration_tests.test -test.failfast -test.v -test.run IntegrationTestSuite -testify.m TestAuction || make -s fail e2e_cellarfees_test: e2e_clean_slate diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index e43bce52..d99da720 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -4,41 +4,88 @@ import ( "context" "time" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/peggyjv/sommelier/v7/x/axelarcork/types" ) func (s *IntegrationTestSuite) TestAxelarCork() { s.Run("Test the axelarcork module", func() { // Set up validator, orchestrator, proposer, query client - /* - val0 := s.chain.validators[0] - val0kb, err := val0.keyring() - s.Require().NoError(err) - val0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", &val0kb, "val", val0.address()) - s.Require().NoError(err) - - orch0 := s.chain.orchestrators[0] - orch0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch0.keyring, "orch", orch0.address()) - s.Require().NoError(err) - orch1 := s.chain.orchestrators[1] - orch1ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch1.keyring, "orch", orch1.address()) - s.Require().NoError(err) - - proposer := s.chain.proposer - proposerCtx, err := s.chain.clientContext("tcp://localhost:26657", proposer.keyring, "proposer", proposer.address()) - s.Require().NoError(err) - propID := uint64(1) - - axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) - */ + val0 := s.chain.validators[0] + val0kb, err := val0.keyring() + s.Require().NoError(err) + val0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", &val0kb, "val", val0.address()) + s.Require().NoError(err) + + orch0 := s.chain.orchestrators[0] + orch0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch0.keyring, "orch", orch0.address()) + s.Require().NoError(err) + //orch1 := s.chain.orchestrators[1] + //orch1ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch1.keyring, "orch", orch1.address()) + //s.Require().NoError(err) + + proposer := s.chain.proposer + proposerCtx, err := s.chain.clientContext("tcp://localhost:26657", proposer.keyring, "proposer", proposer.address()) + s.Require().NoError(err) + propID := uint64(1) + + axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) //////////////// // Happy path // //////////////// + arbitrumChainName := "arbitrum" + arbitrumChainId := uint64(42161) + proxyAddress := "0xEe75bA2C81C04DcA4b0ED6d1B7077c188FEde4d2" + // add chain configuration + s.T().Log("Creating AddChainConfigurationProposal") + addChainConfigurationProp := types.AddChainConfigurationProposal{ + Title: "add a chain configuration", + Description: "adding an arbitrum chain config", + ChainConfiguration: &types.ChainConfiguration{ + Name: arbitrumChainName, + Id: arbitrumChainId, + ProxyAddress: proxyAddress, + }, + } + + addChainConfigurationPropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &addChainConfigurationProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create AddChainConfigurationProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, addChainConfigurationPropMsg) + propID++ + + s.T().Log("Verifying ChainConfiguration correctly added") + chainConfigurationsResponse, err := axelarcorkQueryClient.QueryChainConfigurations(context.Background(), &types.QueryChainConfigurationsRequest{}) + s.Require().NoError(err) + s.Require().Len(chainConfigurationsResponse.Configurations, 1) + chainConfig := chainConfigurationsResponse.Configurations[0] + s.Require().Equal(chainConfig.Name, arbitrumChainName) + s.Require().Equal(chainConfig.Id, arbitrumChainId) + s.Require().Equal(chainConfig.ProxyAddress, proxyAddress) + // add managed cellar + s.T().Log("Creating AddAxelarManagedCellarIDsProposal") + addAxelarManagedCellarIDsProp := types.AddAxelarManagedCellarIDsProposal{ + Title: "add an axelar cellar", + Description: "arbitrum test cellar", + ChainId: arbitrumChainId, + } + // schedule a normal cork // scheduled cork proposal // remove managed cellar From 7ff88f2a1abbf40f122170ffd294d1044ca30d9e Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 20:22:44 -0600 Subject: [PATCH 04/18] computer cork/axelarcork IDHash the same way --- x/axelarcork/types/axelarcork.go | 4 ++-- x/cork/types/cork.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/axelarcork/types/axelarcork.go b/x/axelarcork/types/axelarcork.go index da99cc90..c435d086 100644 --- a/x/axelarcork/types/axelarcork.go +++ b/x/axelarcork/types/axelarcork.go @@ -10,12 +10,12 @@ import ( func (c *AxelarCork) IDHash(blockHeight uint64) []byte { blockHeightBytes := sdk.Uint64ToBigEndian(blockHeight) - + chainIDBytes := sdk.Uint64ToBigEndian(c.ChainId) address := common.HexToAddress(c.TargetContractAddress) return crypto.Keccak256Hash( bytes.Join( - [][]byte{blockHeightBytes, address.Bytes(), c.EncodedContractCall, sdk.Uint64ToBigEndian(c.Deadline)}, + [][]byte{blockHeightBytes, chainIDBytes, address.Bytes(), c.EncodedContractCall}, []byte{}, )).Bytes() } diff --git a/x/cork/types/cork.go b/x/cork/types/cork.go index 739b9985..24c9e318 100644 --- a/x/cork/types/cork.go +++ b/x/cork/types/cork.go @@ -20,12 +20,12 @@ func (c *Cork) InvalidationScope() tmbytes.HexBytes { func (c *Cork) IDHash(blockHeight uint64) []byte { blockHeightBytes := sdk.Uint64ToBigEndian(blockHeight) - + chainIDBytes := sdk.Uint64ToBigEndian(1) // corks are on eth mainnet address := common.HexToAddress(c.TargetContractAddress) return crypto.Keccak256Hash( bytes.Join( - [][]byte{blockHeightBytes, address.Bytes(), c.EncodedContractCall}, + [][]byte{blockHeightBytes, chainIDBytes, address.Bytes(), c.EncodedContractCall}, []byte{}, )).Bytes() } From 7fc65e3747f7601ad0ef85618453bb131c6ea287 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 20:39:42 -0600 Subject: [PATCH 05/18] Fix up axelarcork msgs.go --- x/axelarcork/types/msgs.go | 103 +++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 10 deletions(-) diff --git a/x/axelarcork/types/msgs.go b/x/axelarcork/types/msgs.go index 58f42913..ac13a336 100644 --- a/x/axelarcork/types/msgs.go +++ b/x/axelarcork/types/msgs.go @@ -11,12 +11,16 @@ import ( var ( _ sdk.Msg = &MsgScheduleAxelarCorkRequest{} + _ sdk.Msg = &MsgRelayAxelarCorkRequest{} + _ sdk.Msg = &MsgBumpAxelarCorkGasRequest{} + _ sdk.Msg = &MsgCancelAxelarCorkRequest{} + _ sdk.Msg = &MsgRelayAxelarCorkRequest{} ) const ( - TypeMsgScheduleCorkRequest = "axelar_cork_schedule" - TypeMsgRelayCorkRequest = "axelar_cork_relay" - TypeMsgBumpCorkGasRequest = "axelar_cork_bump_gas" + TypeMsgScheduleAxelarCorkRequest = "axelar_cork_schedule" + TypeMsgRelayAxelarCorkRequest = "axelar_cork_relay" + TypeMsgBumpAxelarCorkGasRequest = "axelar_cork_bump_gas" TypeMsgCancelAxelarCorkRequest = "axelar_cancel_cork" TypeMsgRelayAxelarProxyUpgradeRequest = "axelar_proxy_upgrade_relay" ) @@ -25,8 +29,8 @@ const ( // MsgScheduleAxelarCorkRequest // ////////////////////////////////// -// NewMsgScheduleCorkRequest return a new MsgScheduleAxelarCorkRequest -func NewMsgScheduleCorkRequest(chainID uint64, body []byte, address common.Address, deadline uint64, blockHeight uint64, signer sdk.AccAddress) (*MsgScheduleAxelarCorkRequest, error) { +// NewMsgScheduleAxelarCorkRequest return a new MsgScheduleAxelarCorkRequest +func NewMsgScheduleAxelarCorkRequest(chainID uint64, body []byte, address common.Address, deadline uint64, blockHeight uint64, signer sdk.AccAddress) (*MsgScheduleAxelarCorkRequest, error) { return &MsgScheduleAxelarCorkRequest{ Cork: &AxelarCork{ ChainId: chainID, @@ -43,7 +47,7 @@ func NewMsgScheduleCorkRequest(chainID uint64, body []byte, address common.Addre func (m *MsgScheduleAxelarCorkRequest) Route() string { return ModuleName } // Type implements sdk.Msg -func (m *MsgScheduleAxelarCorkRequest) Type() string { return TypeMsgScheduleCorkRequest } +func (m *MsgScheduleAxelarCorkRequest) Type() string { return TypeMsgScheduleAxelarCorkRequest } // ValidateBasic implements sdk.Msg func (m *MsgScheduleAxelarCorkRequest) ValidateBasic() error { @@ -51,6 +55,10 @@ func (m *MsgScheduleAxelarCorkRequest) ValidateBasic() error { return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) } + if m.BlockHeight == 0 { + return fmt.Errorf("block height must be greater than zero") + } + return m.Cork.ValidateBasic() } @@ -77,11 +85,22 @@ func (m *MsgScheduleAxelarCorkRequest) MustGetSigner() sdk.AccAddress { // MsgRelayAxelarCorkRequest // /////////////////////////////// +// NewMsgRelayAxelarCorkRequest returns a new MsgRelayAxelarCorkRequest +func NewMsgRelayAxelarCorkRequest(signer sdk.Address, token sdk.Coin, fee uint64, chainID uint64, address common.Address) (*MsgRelayAxelarCorkRequest, error) { + return &MsgRelayAxelarCorkRequest{ + Signer: signer.String(), + Token: token, + Fee: fee, + ChainId: chainID, + TargetContractAddress: address.String(), + }, nil +} + // Route implements sdk.Msg func (m *MsgRelayAxelarCorkRequest) Route() string { return ModuleName } // Type implements sdk.Msg -func (m *MsgRelayAxelarCorkRequest) Type() string { return TypeMsgRelayCorkRequest } +func (m *MsgRelayAxelarCorkRequest) Type() string { return TypeMsgRelayAxelarCorkRequest } // ValidateBasic implements sdk.Msg func (m *MsgRelayAxelarCorkRequest) ValidateBasic() error { @@ -89,6 +108,18 @@ func (m *MsgRelayAxelarCorkRequest) ValidateBasic() error { return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) } + if !m.Token.IsPositive() { + return fmt.Errorf("token amount must be positive") + } + + if m.Fee == 0 { + return fmt.Errorf("fee must be greather than zero") + } + + if m.ChainId == 0 { + return fmt.Errorf("chain ID must be greater than zero") + } + if m.TargetContractAddress == "" { return fmt.Errorf("cannot relay a cork to an empty address") } @@ -123,6 +154,16 @@ func (m *MsgRelayAxelarCorkRequest) MustGetSigner() sdk.AccAddress { // MsgRelayAxelarProxyUpgradeRequest // /////////////////////////////////////// +// NewMsgRelayAxelarProxyUpgradeRequest returns a new MsgRelayAxelarProxyUpgradeRequest +func NewMsgRelayAxelarProxyUpgradeRequest(signer sdk.AccAddress, token sdk.Coin, fee uint64, chainID uint64) (*MsgRelayAxelarProxyUpgradeRequest, error) { + return &MsgRelayAxelarProxyUpgradeRequest{ + Signer: signer.String(), + Token: token, + Fee: fee, + ChainId: chainID, + }, nil +} + // Route implements sdk.Msg func (m *MsgRelayAxelarProxyUpgradeRequest) Route() string { return ModuleName } @@ -137,6 +178,18 @@ func (m *MsgRelayAxelarProxyUpgradeRequest) ValidateBasic() error { return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) } + if !m.Token.IsPositive() { + return fmt.Errorf("token amount must be positive") + } + + if m.Fee == 0 { + return fmt.Errorf("fee must be greather than zero") + } + + if m.ChainId == 0 { + return fmt.Errorf("chain ID must be greater than zero") + } + return nil } @@ -163,11 +216,20 @@ func (m *MsgRelayAxelarProxyUpgradeRequest) MustGetSigner() sdk.AccAddress { // MsgBumpAxelarCorkGasRequest // ///////////////////////////////// +// NewMsgBumpAxelarCorkGasRequest returns a new MsgBumpAxelarCorkGasRequest +func NewMsgBumpAxelarCorkGasRequest(signer sdk.AccAddress, token sdk.Coin, messageID string) (*MsgBumpAxelarCorkGasRequest, error) { + return &MsgBumpAxelarCorkGasRequest{ + Signer: signer.String(), + Token: token, + MessageId: messageID, + }, nil +} + // Route implements sdk.Msg func (m *MsgBumpAxelarCorkGasRequest) Route() string { return ModuleName } // Type implements sdk.Msg -func (m *MsgBumpAxelarCorkGasRequest) Type() string { return TypeMsgBumpCorkGasRequest } +func (m *MsgBumpAxelarCorkGasRequest) Type() string { return TypeMsgBumpAxelarCorkGasRequest } // ValidateBasic implements sdk.Msg func (m *MsgBumpAxelarCorkGasRequest) ValidateBasic() error { @@ -175,6 +237,14 @@ func (m *MsgBumpAxelarCorkGasRequest) ValidateBasic() error { return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, err.Error()) } + if !m.Token.IsPositive() { + return fmt.Errorf("token amount must be positive") + } + + if m.MessageId == "" { + return fmt.Errorf("message ID must be present") + } + return nil } @@ -201,11 +271,20 @@ func (m *MsgBumpAxelarCorkGasRequest) MustGetSigner() sdk.AccAddress { // MsgCancelAxelarCorkRequest // //////////////////////////////// +// NewMsgCancelAxelarCorkRequest returns a new MsgCancelAxelarCorkRequest +func NewMsgCancelAxelarCorkRequest(signer sdk.AccAddress, chainID uint64, address common.Address) (*MsgCancelAxelarCorkRequest, error) { + return &MsgCancelAxelarCorkRequest{ + Signer: signer.String(), + ChainId: chainID, + TargetContractAddress: address.String(), + }, nil +} + // Route implements sdk.Msg func (m *MsgCancelAxelarCorkRequest) Route() string { return ModuleName } // Type implements sdk.Msg -func (m *MsgCancelAxelarCorkRequest) Type() string { return TypeMsgBumpCorkGasRequest } +func (m *MsgCancelAxelarCorkRequest) Type() string { return TypeMsgCancelAxelarCorkRequest } // ValidateBasic implements sdk.Msg func (m *MsgCancelAxelarCorkRequest) ValidateBasic() error { @@ -214,13 +293,17 @@ func (m *MsgCancelAxelarCorkRequest) ValidateBasic() error { } if m.TargetContractAddress == "" { - return fmt.Errorf("cannot relay a cork to an empty address") + return fmt.Errorf("cannot cancel a cork to an empty address") } if !common.IsHexAddress(m.TargetContractAddress) { return errorsmod.Wrapf(ErrInvalidEVMAddress, "%s", m.TargetContractAddress) } + if m.ChainId == 0 { + return fmt.Errorf("chain ID must be greater than zero") + } + return nil } From f2bb49c61cd0aa8dc238b5bb403e91cb2ed97368 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 20:58:16 -0600 Subject: [PATCH 06/18] WIP on axelarcork integration test --- integration_tests/axelarcork_test.go | 92 ++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index d99da720..a283c68e 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -2,6 +2,7 @@ package integration_tests import ( "context" + "encoding/hex" "time" "cosmossdk.io/math" @@ -79,20 +80,103 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Equal(chainConfig.ProxyAddress, proxyAddress) // add managed cellar - s.T().Log("Creating AddAxelarManagedCellarIDsProposal") + s.T().Log("Creating AddAxelarManagedCellarIDsProposal for counter contract") addAxelarManagedCellarIDsProp := types.AddAxelarManagedCellarIDsProposal{ - Title: "add an axelar cellar", - Description: "arbitrum test cellar", + Title: "add the counter contract as axelar cellar", + Description: "arbitrum counter contract", ChainId: arbitrumChainId, + CellarIds: &types.CellarIDSet{ + Ids: []string{ + counterContract.Hex(), + }, + }, } + addAxelarManagedCellarIDsPropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &addAxelarManagedCellarIDsProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create AddAxelarManagedCellarIDsProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, addAxelarManagedCellarIDsPropMsg) + propID++ + + s.T().Log("Verifying CellarID correctly added") + cellarIDsResponse, err := axelarcorkQueryClient.QueryCellarIDsByChainID(context.Background(), &types.QueryCellarIDsByChainIDRequest{ChainId: arbitrumChainId}) + s.Require().NoError(err) + s.Require().Len(cellarIDsResponse.CellarIds, 1) + s.Require().Equal(cellarIDsResponse.CellarIds[0], counterContract.Hex()) + + s.T().Log("Schedule an axelar cork for the future") + node, err := proposerCtx.GetNode() + s.Require().NoError(err) + status, err := node.Status(context.Background()) + s.Require().NoError(err) + currentBlockHeight := status.SyncInfo.LatestBlockHeight + targetBlockHeight := currentBlockHeight + 15 + deadline := uint64(time.Now().Unix() + int64(time.Hour.Seconds())) + + s.T().Logf("Scheduling axelar cork calls for height %d", targetBlockHeight) + axelarCork := types.AxelarCork{ + EncodedContractCall: ABIEncodedInc(), + ChainId: arbitrumChainId, + TargetContractAddress: counterContract.Hex(), + Deadline: deadline, + } + axelarCorkID := axelarCork.IDHash(uint64(targetBlockHeight)) + s.T().Logf("Axelar cork ID is %s", hex.EncodeToString(axelarCorkID)) + for i, orch := range s.chain.orchestrators { + i := i + orch := orch + clientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch.keyring, "orch", orch.address()) + s.Require().NoError(err) + axelarCorkMsg, err := types.NewMsgScheduleAxelarCorkRequest( + arbitrumChainId, + ABIEncodedInc(), + counterContract, + deadline, + uint64(targetBlockHeight), + orch.address()) + s.Require().NoError(err, "Failed to construct axelar cork") + response, err := s.chain.sendMsgs(*clientCtx, axelarCorkMsg) + s.Require().NoError(err, "Failed to send axelar cork to node %d", i) + if response.Code != 0 { + if response.Code != 32 { + s.T().Log(response) + } + } + + s.T().Logf("Axelar cork msg for orch %d sent successfully", i) + } + + s.T().Log("Verifying scheduled axelar corks were created") + scheduledCorksResponse, err := axelarcorkQueryClient.QueryScheduledCorks(context.Background(), &types.QueryScheduledCorksRequest{ChainId: arbitrumChainId}) + s.Require().NoError(err) + s.Require().Len(scheduledCorksResponse.Corks, 4) + cork0 := scheduledCorksResponse.Corks[0] + //cork1 := scheduledCorksResponse.Corks[1] + //cork2 := scheduledCorksResponse.Corks[2] + //cork3 := scheduledCorksResponse.Corks[3] + s.Require().Equal(cork0.Cork.EncodedContractCall, ABIEncodedInc()) + s.Require().Equal(cork0.Cork.ChainId, arbitrumChainId) + s.Require().Equal(cork0.Cork.TargetContractAddress, counterContract.Hex()) + s.Require().Equal(cork0.Cork.Deadline, deadline) + s.Require().Equal(cork0.BlockHeight, targetBlockHeight) + s.Require().Equal(cork0.Id, axelarCorkID) + s.Require().Equal(cork0.Validator, val0.address()) + // schedule a normal cork // scheduled cork proposal // remove managed cellar // upgrade proxy proposal // upgrade but then cancel proxy proposal // remove chain configuration - }) } From 2ac8d038ada5029d7f73c7f213145101c8393538 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 20:58:35 -0600 Subject: [PATCH 07/18] go mod tidy --- go.mod | 4 ++-- go.sum | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index b5ad5ff1..c440fe3a 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/peggyjv/sommelier/v7 go 1.19 require ( + cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.0-rc.0 github.com/cosmos/cosmos-sdk v0.46.14 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ibc-go/v6 v6.2.0 @@ -34,8 +36,6 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.12.0 // indirect cloud.google.com/go/storage v1.28.1 // indirect - cosmossdk.io/errors v1.0.0-beta.7 // indirect - cosmossdk.io/math v1.0.0-rc.0 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect diff --git a/go.sum b/go.sum index 7eb30ae3..df96781c 100644 --- a/go.sum +++ b/go.sum @@ -842,10 +842,6 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/peggyjv/gravity-bridge/module/v4 v4.0.0-20231130211750-e1fa9902c9d9 h1:3aqB5WI8S1FtvsoU7HAM+35czUtDvEZJa1feK8/9xRg= -github.com/peggyjv/gravity-bridge/module/v4 v4.0.0-20231130211750-e1fa9902c9d9/go.mod h1:biwoVDKWggMYtzuUZOuqaJD8B40XHrXg3zOJjeAhT78= -github.com/peggyjv/gravity-bridge/module/v4 v4.0.0-20231211214131-bf2a31eb986f h1:xaVjypGpS3+VUXzEb2YFaTK632Id6jVWY1ViS4nljJs= -github.com/peggyjv/gravity-bridge/module/v4 v4.0.0-20231211214131-bf2a31eb986f/go.mod h1:n8Jj3X+w6q0Xz19w8feRRl2sfIGV+3FGU4anzXBQGbA= github.com/peggyjv/gravity-bridge/module/v4 v4.0.0 h1:jH10FodlMxzGdbxAxeNpsql9qhYDlmwqciwOuwuU0LQ= github.com/peggyjv/gravity-bridge/module/v4 v4.0.0/go.mod h1:n8Jj3X+w6q0Xz19w8feRRl2sfIGV+3FGU4anzXBQGbA= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= From 6006ef4f95b24a0c30b1e63eb93a54aa7e67d06b Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 21:00:02 -0600 Subject: [PATCH 08/18] appease linter --- integration_tests/axelarcork_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index a283c68e..52da8e7e 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -40,7 +40,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { //////////////// arbitrumChainName := "arbitrum" - arbitrumChainId := uint64(42161) + arbitrumChainID := uint64(42161) proxyAddress := "0xEe75bA2C81C04DcA4b0ED6d1B7077c188FEde4d2" // add chain configuration @@ -50,7 +50,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { Description: "adding an arbitrum chain config", ChainConfiguration: &types.ChainConfiguration{ Name: arbitrumChainName, - Id: arbitrumChainId, + Id: arbitrumChainID, ProxyAddress: proxyAddress, }, } @@ -76,7 +76,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Len(chainConfigurationsResponse.Configurations, 1) chainConfig := chainConfigurationsResponse.Configurations[0] s.Require().Equal(chainConfig.Name, arbitrumChainName) - s.Require().Equal(chainConfig.Id, arbitrumChainId) + s.Require().Equal(chainConfig.Id, arbitrumChainID) s.Require().Equal(chainConfig.ProxyAddress, proxyAddress) // add managed cellar @@ -84,7 +84,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { addAxelarManagedCellarIDsProp := types.AddAxelarManagedCellarIDsProposal{ Title: "add the counter contract as axelar cellar", Description: "arbitrum counter contract", - ChainId: arbitrumChainId, + ChainId: arbitrumChainID, CellarIds: &types.CellarIDSet{ Ids: []string{ counterContract.Hex(), @@ -105,10 +105,10 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err, "Unable to create AddAxelarManagedCellarIDsProposal") s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, addAxelarManagedCellarIDsPropMsg) - propID++ + //propID++ s.T().Log("Verifying CellarID correctly added") - cellarIDsResponse, err := axelarcorkQueryClient.QueryCellarIDsByChainID(context.Background(), &types.QueryCellarIDsByChainIDRequest{ChainId: arbitrumChainId}) + cellarIDsResponse, err := axelarcorkQueryClient.QueryCellarIDsByChainID(context.Background(), &types.QueryCellarIDsByChainIDRequest{ChainId: arbitrumChainID}) s.Require().NoError(err) s.Require().Len(cellarIDsResponse.CellarIds, 1) s.Require().Equal(cellarIDsResponse.CellarIds[0], counterContract.Hex()) @@ -125,7 +125,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.T().Logf("Scheduling axelar cork calls for height %d", targetBlockHeight) axelarCork := types.AxelarCork{ EncodedContractCall: ABIEncodedInc(), - ChainId: arbitrumChainId, + ChainId: arbitrumChainID, TargetContractAddress: counterContract.Hex(), Deadline: deadline, } @@ -137,7 +137,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { clientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch.keyring, "orch", orch.address()) s.Require().NoError(err) axelarCorkMsg, err := types.NewMsgScheduleAxelarCorkRequest( - arbitrumChainId, + arbitrumChainID, ABIEncodedInc(), counterContract, deadline, @@ -156,7 +156,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { } s.T().Log("Verifying scheduled axelar corks were created") - scheduledCorksResponse, err := axelarcorkQueryClient.QueryScheduledCorks(context.Background(), &types.QueryScheduledCorksRequest{ChainId: arbitrumChainId}) + scheduledCorksResponse, err := axelarcorkQueryClient.QueryScheduledCorks(context.Background(), &types.QueryScheduledCorksRequest{ChainId: arbitrumChainID}) s.Require().NoError(err) s.Require().Len(scheduledCorksResponse.Corks, 4) cork0 := scheduledCorksResponse.Corks[0] @@ -164,7 +164,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { //cork2 := scheduledCorksResponse.Corks[2] //cork3 := scheduledCorksResponse.Corks[3] s.Require().Equal(cork0.Cork.EncodedContractCall, ABIEncodedInc()) - s.Require().Equal(cork0.Cork.ChainId, arbitrumChainId) + s.Require().Equal(cork0.Cork.ChainId, arbitrumChainID) s.Require().Equal(cork0.Cork.TargetContractAddress, counterContract.Hex()) s.Require().Equal(cork0.Cork.Deadline, deadline) s.Require().Equal(cork0.BlockHeight, targetBlockHeight) From 4d174ca1528c4ee31d0a44f8a88c4f3a5b9a7b54 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 21:23:50 -0600 Subject: [PATCH 09/18] move creation of axelar keeper to after gravity --- app/app.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/app.go b/app/app.go index 343a0c93..0066a05d 100644 --- a/app/app.go +++ b/app/app.go @@ -418,19 +418,6 @@ func NewSommelierApp( app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, ) - // create axelar cork keeper - app.AxelarCorkKeeper = axelarcorkkeeper.NewKeeper( - appCodec, - keys[axelarcorktypes.StoreKey], - app.GetSubspace(axelarcorktypes.ModuleName), - app.AccountKeeper, - app.BankKeeper, - app.StakingKeeper, - app.TransferKeeper, - app.DistrKeeper, - app.IBCKeeper.ChannelKeeper, - app.GravityKeeper, - ) transferModule := ibctransfer.NewAppModule(app.TransferKeeper) transferIBCModule := ibctransfer.NewIBCModule(app.TransferKeeper) var transferStack ibcporttypes.IBCModule = transferIBCModule @@ -459,6 +446,20 @@ func NewSommelierApp( app.ModuleAccountAddressesToNames([]string{distrtypes.ModuleName}), ) + // create axelar cork keeper + app.AxelarCorkKeeper = axelarcorkkeeper.NewKeeper( + appCodec, + keys[axelarcorktypes.StoreKey], + app.GetSubspace(axelarcorktypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + app.TransferKeeper, + app.DistrKeeper, + app.IBCKeeper.ChannelKeeper, + app.GravityKeeper, + ) + app.CorkKeeper = corkkeeper.NewKeeper( appCodec, keys[corktypes.StoreKey], app.GetSubspace(corktypes.ModuleName), app.StakingKeeper, app.GravityKeeper, From 0665ad5f8291272ca0d948f211286cd44f34826e Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 22:06:50 -0600 Subject: [PATCH 10/18] fix creation of msg for scheduling an axelar cork --- x/axelarcork/types/msgs.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/axelarcork/types/msgs.go b/x/axelarcork/types/msgs.go index ac13a336..03fc2702 100644 --- a/x/axelarcork/types/msgs.go +++ b/x/axelarcork/types/msgs.go @@ -38,6 +38,7 @@ func NewMsgScheduleAxelarCorkRequest(chainID uint64, body []byte, address common TargetContractAddress: address.String(), Deadline: deadline, }, + ChainId: chainID, BlockHeight: blockHeight, Signer: signer.String(), }, nil From 07de54cadc0cad1892c01e1226ba4d9f759fe8fd Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 22:07:05 -0600 Subject: [PATCH 11/18] WIP for axelar integration test --- integration_tests/axelarcork_test.go | 13 +++++++------ integration_tests/validator.go | 4 ++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index 52da8e7e..9cd126a9 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -119,7 +119,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { status, err := node.Status(context.Background()) s.Require().NoError(err) currentBlockHeight := status.SyncInfo.LatestBlockHeight - targetBlockHeight := currentBlockHeight + 15 + targetBlockHeight := uint64(currentBlockHeight + 15) deadline := uint64(time.Now().Unix() + int64(time.Hour.Seconds())) s.T().Logf("Scheduling axelar cork calls for height %d", targetBlockHeight) @@ -129,8 +129,9 @@ func (s *IntegrationTestSuite) TestAxelarCork() { TargetContractAddress: counterContract.Hex(), Deadline: deadline, } - axelarCorkID := axelarCork.IDHash(uint64(targetBlockHeight)) - s.T().Logf("Axelar cork ID is %s", hex.EncodeToString(axelarCorkID)) + axelarCorkID := axelarCork.IDHash(targetBlockHeight) + axelarCorkIDHex := hex.EncodeToString(axelarCorkID) + s.T().Logf("Axelar cork ID is %s", axelarCorkIDHex) for i, orch := range s.chain.orchestrators { i := i orch := orch @@ -141,7 +142,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { ABIEncodedInc(), counterContract, deadline, - uint64(targetBlockHeight), + targetBlockHeight, orch.address()) s.Require().NoError(err, "Failed to construct axelar cork") response, err := s.chain.sendMsgs(*clientCtx, axelarCorkMsg) @@ -168,8 +169,8 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Equal(cork0.Cork.TargetContractAddress, counterContract.Hex()) s.Require().Equal(cork0.Cork.Deadline, deadline) s.Require().Equal(cork0.BlockHeight, targetBlockHeight) - s.Require().Equal(cork0.Id, axelarCorkID) - s.Require().Equal(cork0.Validator, val0.address()) + s.Require().Equal(cork0.Id, axelarCorkIDHex) + //s.Require().Equal(cork0.Validator, val0.address().String()) // schedule a normal cork // scheduled cork proposal diff --git a/integration_tests/validator.go b/integration_tests/validator.go index 66f7a5c1..61659806 100644 --- a/integration_tests/validator.go +++ b/integration_tests/validator.go @@ -357,6 +357,10 @@ func (v *validator) address() sdk.AccAddress { return addr } +func (v *validator) validatorAddress() sdk.ValAddress { + return nil +} + func (v *validator) pubKey() cryptotypes.PubKey { pubKey, err := v.keyRecord.GetPubKey() if err != nil { From e2e71239168c760569082563ff52595aa3562344 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 22:28:45 -0600 Subject: [PATCH 12/18] check all the scheduled corks --- integration_tests/axelarcork_test.go | 36 ++++++++++++++++++++++++---- integration_tests/validator.go | 2 +- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index 9cd126a9..6d316811 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -3,6 +3,7 @@ package integration_tests import ( "context" "encoding/hex" + "sort" "time" "cosmossdk.io/math" @@ -33,6 +34,12 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err) propID := uint64(1) + sortedValidators := make([]string, 4) + for i, validator := range s.chain.validators { + sortedValidators[i] = validator.validatorAddress().String() + } + sort.Sort(sort.StringSlice(sortedValidators)) + axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) //////////////// @@ -161,16 +168,37 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err) s.Require().Len(scheduledCorksResponse.Corks, 4) cork0 := scheduledCorksResponse.Corks[0] - //cork1 := scheduledCorksResponse.Corks[1] - //cork2 := scheduledCorksResponse.Corks[2] - //cork3 := scheduledCorksResponse.Corks[3] + cork1 := scheduledCorksResponse.Corks[1] + cork2 := scheduledCorksResponse.Corks[2] + cork3 := scheduledCorksResponse.Corks[3] s.Require().Equal(cork0.Cork.EncodedContractCall, ABIEncodedInc()) s.Require().Equal(cork0.Cork.ChainId, arbitrumChainID) s.Require().Equal(cork0.Cork.TargetContractAddress, counterContract.Hex()) s.Require().Equal(cork0.Cork.Deadline, deadline) s.Require().Equal(cork0.BlockHeight, targetBlockHeight) s.Require().Equal(cork0.Id, axelarCorkIDHex) - //s.Require().Equal(cork0.Validator, val0.address().String()) + s.Require().Equal(cork1.Cork.EncodedContractCall, ABIEncodedInc()) + s.Require().Equal(cork1.Cork.ChainId, arbitrumChainID) + s.Require().Equal(cork1.Cork.TargetContractAddress, counterContract.Hex()) + s.Require().Equal(cork1.Cork.Deadline, deadline) + s.Require().Equal(cork1.BlockHeight, targetBlockHeight) + s.Require().Equal(cork1.Id, axelarCorkIDHex) + s.Require().Equal(cork2.Cork.EncodedContractCall, ABIEncodedInc()) + s.Require().Equal(cork2.Cork.ChainId, arbitrumChainID) + s.Require().Equal(cork2.Cork.TargetContractAddress, counterContract.Hex()) + s.Require().Equal(cork2.Cork.Deadline, deadline) + s.Require().Equal(cork2.BlockHeight, targetBlockHeight) + s.Require().Equal(cork2.Id, axelarCorkIDHex) + s.Require().Equal(cork3.Cork.EncodedContractCall, ABIEncodedInc()) + s.Require().Equal(cork3.Cork.ChainId, arbitrumChainID) + s.Require().Equal(cork3.Cork.TargetContractAddress, counterContract.Hex()) + s.Require().Equal(cork3.Cork.Deadline, deadline) + s.Require().Equal(cork3.BlockHeight, targetBlockHeight) + s.Require().Equal(cork3.Id, axelarCorkIDHex) + + corkValidators := []string{cork0.Validator, cork1.Validator, cork2.Validator, cork3.Validator} + sort.Sort(sort.StringSlice(corkValidators)) + s.Require().Equal(corkValidators, sortedValidators) // schedule a normal cork // scheduled cork proposal diff --git a/integration_tests/validator.go b/integration_tests/validator.go index 61659806..c84afc7a 100644 --- a/integration_tests/validator.go +++ b/integration_tests/validator.go @@ -358,7 +358,7 @@ func (v *validator) address() sdk.AccAddress { } func (v *validator) validatorAddress() sdk.ValAddress { - return nil + return sdk.ValAddress(v.address()) } func (v *validator) pubKey() cryptotypes.PubKey { From 125212681940e0158832db57931e25d5d8cd4d40 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 22:34:48 -0600 Subject: [PATCH 13/18] v7 upgrade uses zero-size slices with capacities --- app/upgrades/v7/upgrades.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/upgrades/v7/upgrades.go b/app/upgrades/v7/upgrades.go index e87c352f..237c33c6 100644 --- a/app/upgrades/v7/upgrades.go +++ b/app/upgrades/v7/upgrades.go @@ -265,7 +265,7 @@ func pubsubInitGenesis(ctx sdk.Context, pubsubKeeper pubsubkeeper.Keeper) { } // Set 7seas publisher intents for existing cellars - publisherIntents := make([]*pubsubtypes.PublisherIntent, 25) + publisherIntents := make([]*pubsubtypes.PublisherIntent, 0, 25) for _, cellar := range cellars { publisherIntents = append(publisherIntents, &pubsubtypes.PublisherIntent{ SubscriptionId: cellar, @@ -276,7 +276,7 @@ func pubsubInitGenesis(ctx sdk.Context, pubsubKeeper pubsubkeeper.Keeper) { } // Set default subscriptions for 7seas as the publisher for existing cellars - defaultSubscriptions := make([]*pubsubtypes.DefaultSubscription, 25) + defaultSubscriptions := make([]*pubsubtypes.DefaultSubscription, 0, 25) for _, cellar := range cellars { defaultSubscriptions = append(defaultSubscriptions, &pubsubtypes.DefaultSubscription{ SubscriptionId: cellar, @@ -286,7 +286,7 @@ func pubsubInitGenesis(ctx sdk.Context, pubsubKeeper pubsubkeeper.Keeper) { // Create subscribers and intents for existing validators subscribers := createSubscribers() - subscriberIntents := make([]*pubsubtypes.SubscriberIntent, 875) + subscriberIntents := make([]*pubsubtypes.SubscriberIntent, 0, 875) for _, subscriber := range subscribers { for _, cellar := range cellars { subscriberIntents = append(subscriberIntents, &pubsubtypes.SubscriberIntent{ @@ -318,7 +318,7 @@ func pubsubInitGenesis(ctx sdk.Context, pubsubKeeper pubsubkeeper.Keeper) { // leaving out made_in_block because I can't find their validator on-chain // blockhunters hadn't been merged, but verified and added here func createSubscribers() []*pubsubtypes.Subscriber { - subscribers := make([]*pubsubtypes.Subscriber, 35) + subscribers := make([]*pubsubtypes.Subscriber, 0, 35) subscribers = append(subscribers, &pubsubtypes.Subscriber{ Address: "somm1s2q8avjykkztudpl8k60f0ns4v5mvnjp5t366c", From 5c0f59fa267bea98fbb9f8425f3eddf2f9c8b7a8 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Thu, 14 Dec 2023 23:47:23 -0600 Subject: [PATCH 14/18] integration tests normal and scheduled corks --- integration_tests/axelarcork_test.go | 90 ++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index 6d316811..488d2cba 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -10,6 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/ethereum/go-ethereum/common" + "github.com/golang/protobuf/proto" "github.com/peggyjv/sommelier/v7/x/axelarcork/types" ) @@ -34,13 +36,14 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err) propID := uint64(1) - sortedValidators := make([]string, 4) - for i, validator := range s.chain.validators { - sortedValidators[i] = validator.validatorAddress().String() + sortedValidators := make([]string, 0, 4) + for _, validator := range s.chain.validators { + sortedValidators = append(sortedValidators, validator.validatorAddress().String()) } sort.Sort(sort.StringSlice(sortedValidators)) axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) + govQueryClient := govtypesv1beta1.NewQueryClient(orch0ClientCtx) //////////////// // Happy path // @@ -112,7 +115,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err, "Unable to create AddAxelarManagedCellarIDsProposal") s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, addAxelarManagedCellarIDsPropMsg) - //propID++ + propID++ s.T().Log("Verifying CellarID correctly added") cellarIDsResponse, err := axelarcorkQueryClient.QueryCellarIDsByChainID(context.Background(), &types.QueryCellarIDsByChainIDRequest{ChainId: arbitrumChainID}) @@ -200,8 +203,83 @@ func (s *IntegrationTestSuite) TestAxelarCork() { sort.Sort(sort.StringSlice(corkValidators)) s.Require().Equal(corkValidators, sortedValidators) - // schedule a normal cork - // scheduled cork proposal + s.T().Log("Waiting for scheduled height") + s.Require().Eventuallyf(func() bool { + node, err := val0ClientCtx.GetNode() + s.Require().NoError(err) + status, err := node.Status(context.Background()) + s.Require().NoError(err) + + currentHeight := status.SyncInfo.LatestBlockHeight + if currentHeight > int64(targetBlockHeight+1) { + return true + } else if currentHeight < int64(targetBlockHeight) { + scheduledCorksResponse, err := axelarcorkQueryClient.QueryScheduledCorks(context.Background(), &types.QueryScheduledCorksRequest{ChainId: arbitrumChainID}) + if err != nil { + s.T().Logf("error: %s", err) + return false + } + + // verify that the scheduled corks have not yet been consumed + s.Require().Len(scheduledCorksResponse.Corks, len(s.chain.validators)) + } + + return false + }, 3*time.Minute, 1*time.Second, "never reached scheduled height") + + s.T().Log("Verifying axelar cork was approved") + corkResultResponse, err := axelarcorkQueryClient.QueryCorkResult(context.Background(), &types.QueryCorkResultRequest{Id: axelarCorkIDHex, ChainId: arbitrumChainID}) + s.Require().NoError(err) + s.Require().True(corkResultResponse.CorkResult.Approved) + s.Require().True(sdk.MustNewDecFromStr(corkResultResponse.CorkResult.ApprovalPercentage).GT(corkVoteThreshold)) + s.Require().Equal(counterContract, common.HexToAddress(corkResultResponse.CorkResult.Cork.TargetContractAddress)) + + s.T().Log("Verifying scheduled axelar corks were deleted") + scheduledCorksByHeightResponse, err := axelarcorkQueryClient.QueryScheduledCorksByBlockHeight(context.Background(), &types.QueryScheduledCorksByBlockHeightRequest{BlockHeight: targetBlockHeight, ChainId: arbitrumChainID}) + s.Require().NoError(err) + s.Require().Len(scheduledCorksByHeightResponse.Corks, 0) + + protoJSON := "{\"cellar_id\":\"0x123801a7D398351b8bE11C439e05C5B3259aeC9B\",\"cellar_v1\":{\"some_fuction\":{\"function_args\":{}},\"block_height\":12345}}" + s.T().Log("Creating AxelarScheduledCorkProposal for counter contract") + addAxelarScheduledCorkProp := types.AxelarScheduledCorkProposal{ + Title: "schedule a cork to the counter contract", + Description: "arbitrum counter contract scheduled cork", + BlockHeight: targetBlockHeight, + ChainId: arbitrumChainID, + TargetContractAddress: counterContract.Hex(), + ContractCallProtoJson: protoJSON, + Deadline: deadline, + } + + addAxelarScheduledCorkPropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &addAxelarScheduledCorkProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create AxelarScheduledCorkProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, addAxelarScheduledCorkPropMsg) + //propID++ + + s.T().Log("Verifying the details of the AxelarScheduledCorkProposal proposal") + proposalResponse, err := govQueryClient.Proposal(context.Background(), &govtypesv1beta1.QueryProposalRequest{ProposalId: propID}) + s.Require().NoError(err) + propContent := &types.AxelarScheduledCorkProposal{} + err = proto.Unmarshal(proposalResponse.Proposal.Content.Value, propContent) + s.Require().NoError(err, "couldn't unmarshal into proposal") + s.Require().Equal(propContent.Title, addAxelarScheduledCorkProp.Title) + s.Require().Equal(propContent.Description, addAxelarScheduledCorkProp.Description) + s.Require().Equal(propContent.BlockHeight, addAxelarScheduledCorkProp.BlockHeight) + s.Require().Equal(propContent.ChainId, addAxelarScheduledCorkProp.ChainId) + s.Require().Equal(propContent.TargetContractAddress, addAxelarScheduledCorkProp.TargetContractAddress) + s.Require().Equal(propContent.ContractCallProtoJson, addAxelarScheduledCorkProp.ContractCallProtoJson) + s.Require().Equal(propContent.Deadline, addAxelarScheduledCorkProp.Deadline) + // remove managed cellar // upgrade proxy proposal // upgrade but then cancel proxy proposal From 54a43d2e7afcf3b10736a6ee5fdbfea6c83d623a Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Fri, 15 Dec 2023 00:33:56 -0600 Subject: [PATCH 15/18] Set the ChainID in upgrade data --- x/axelarcork/keeper/proposal_handler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/axelarcork/keeper/proposal_handler.go b/x/axelarcork/keeper/proposal_handler.go index 43bec67e..7dca52e6 100644 --- a/x/axelarcork/keeper/proposal_handler.go +++ b/x/axelarcork/keeper/proposal_handler.go @@ -181,6 +181,7 @@ func HandleUpgradeAxelarProxyContractProposal(ctx sdk.Context, k Keeper, p types } upgradeData := types.AxelarUpgradeData{ + ChainId: p.ChainId, Payload: payload, ExecutableHeightThreshold: ctx.BlockHeight() + int64(types.DefaultExecutableHeightThreshold), } From 0d148ae5312957009fe1081097c86419c8cc4e30 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Fri, 15 Dec 2023 00:43:27 -0600 Subject: [PATCH 16/18] integration test for upgrade proxy proposal --- integration_tests/axelarcork_test.go | 49 ++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index 488d2cba..dbc66c87 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -264,7 +264,6 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err, "Unable to create AxelarScheduledCorkProposal") s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, addAxelarScheduledCorkPropMsg) - //propID++ s.T().Log("Verifying the details of the AxelarScheduledCorkProposal proposal") proposalResponse, err := govQueryClient.Proposal(context.Background(), &govtypesv1beta1.QueryProposalRequest{ProposalId: propID}) @@ -279,10 +278,54 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Equal(propContent.TargetContractAddress, addAxelarScheduledCorkProp.TargetContractAddress) s.Require().Equal(propContent.ContractCallProtoJson, addAxelarScheduledCorkProp.ContractCallProtoJson) s.Require().Equal(propContent.Deadline, addAxelarScheduledCorkProp.Deadline) + propID++ + + s.T().Log("Creating UpgradeAxelarProxyContractProposal") + newProxyAddress := "0x438087f7c226A89762a791F187d7c3D4a0e95ae6" + upgradeAxelarProxyContractProp := types.UpgradeAxelarProxyContractProposal{ + Title: "upgrade an axelar proxy contract", + Description: "arbitrum is getting a new proxy", + ChainId: arbitrumChainID, + NewProxyAddress: newProxyAddress, + } + + upgradeAxelarProxyContractPropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &upgradeAxelarProxyContractProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create UpgradeAxelarProxyContractProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, upgradeAxelarProxyContractPropMsg) + //propID++ + + s.T().Log("Verifying upgrade data added correctly") + node, err = val0ClientCtx.GetNode() + s.Require().NoError(err) + status, err = node.Status(context.Background()) + s.Require().NoError(err) + + threshold := int64(types.DefaultExecutableHeightThreshold) + currentHeight := status.SyncInfo.LatestBlockHeight + upgradeResponse, err := axelarcorkQueryClient.QueryAxelarProxyUpgradeData(context.Background(), &types.QueryAxelarProxyUpgradeDataRequest{}) + s.Require().NoError(err) + s.Require().Len(upgradeResponse.ProxyUpgradeData, 1) + upgradeData := upgradeResponse.ProxyUpgradeData[0] + s.Require().Equal(upgradeData.ChainId, arbitrumChainID) + // an approximation but timing is difficult + s.Require().Less(upgradeData.ExecutableHeightThreshold, currentHeight+threshold+5) + s.Require().Greater(upgradeData.ExecutableHeightThreshold, currentHeight+threshold-5) + encodedProxy, _, err := types.DecodeUpgradeArgs(upgradeData.Payload) + s.Require().NoError(err) + s.Require().Equal(encodedProxy, newProxyAddress) + // cancel proxy upgrade // remove managed cellar - // upgrade proxy proposal - // upgrade but then cancel proxy proposal // remove chain configuration }) } From 6ea106a03c67a9ab1c728d240bedce75cadca257 Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Fri, 15 Dec 2023 00:51:04 -0600 Subject: [PATCH 17/18] appease linter --- integration_tests/axelarcork_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index dbc66c87..c16c3be4 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -11,7 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/ethereum/go-ethereum/common" - "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/proto" //nolint:staticcheck "github.com/peggyjv/sommelier/v7/x/axelarcork/types" ) @@ -40,7 +40,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { for _, validator := range s.chain.validators { sortedValidators = append(sortedValidators, validator.validatorAddress().String()) } - sort.Sort(sort.StringSlice(sortedValidators)) + sort.Strings(sortedValidators) axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) govQueryClient := govtypesv1beta1.NewQueryClient(orch0ClientCtx) @@ -200,7 +200,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Equal(cork3.Id, axelarCorkIDHex) corkValidators := []string{cork0.Validator, cork1.Validator, cork2.Validator, cork3.Validator} - sort.Sort(sort.StringSlice(corkValidators)) + sort.Strings(corkValidators) s.Require().Equal(corkValidators, sortedValidators) s.T().Log("Waiting for scheduled height") From b475934eaedd4684cb813d049c751b4f06cf1a4b Mon Sep 17 00:00:00 2001 From: Eric Bolten Date: Fri, 15 Dec 2023 12:29:02 -0600 Subject: [PATCH 18/18] full axelar integration test --- integration_tests/axelarcork_test.go | 136 ++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 14 deletions(-) diff --git a/integration_tests/axelarcork_test.go b/integration_tests/axelarcork_test.go index c16c3be4..d8100641 100644 --- a/integration_tests/axelarcork_test.go +++ b/integration_tests/axelarcork_test.go @@ -17,7 +17,10 @@ import ( func (s *IntegrationTestSuite) TestAxelarCork() { s.Run("Test the axelarcork module", func() { - // Set up validator, orchestrator, proposer, query client + /////////// + // Setup // + /////////// + val0 := s.chain.validators[0] val0kb, err := val0.keyring() s.Require().NoError(err) @@ -27,9 +30,6 @@ func (s *IntegrationTestSuite) TestAxelarCork() { orch0 := s.chain.orchestrators[0] orch0ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch0.keyring, "orch", orch0.address()) s.Require().NoError(err) - //orch1 := s.chain.orchestrators[1] - //orch1ClientCtx, err := s.chain.clientContext("tcp://localhost:26657", orch1.keyring, "orch", orch1.address()) - //s.Require().NoError(err) proposer := s.chain.proposer proposerCtx, err := s.chain.clientContext("tcp://localhost:26657", proposer.keyring, "proposer", proposer.address()) @@ -45,15 +45,14 @@ func (s *IntegrationTestSuite) TestAxelarCork() { axelarcorkQueryClient := types.NewQueryClient(val0ClientCtx) govQueryClient := govtypesv1beta1.NewQueryClient(orch0ClientCtx) - //////////////// - // Happy path // - //////////////// + ///////////////////////////// + // Add chain configuration // + ///////////////////////////// arbitrumChainName := "arbitrum" arbitrumChainID := uint64(42161) proxyAddress := "0xEe75bA2C81C04DcA4b0ED6d1B7077c188FEde4d2" - // add chain configuration s.T().Log("Creating AddChainConfigurationProposal") addChainConfigurationProp := types.AddChainConfigurationProposal{ Title: "add a chain configuration", @@ -89,7 +88,10 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Equal(chainConfig.Id, arbitrumChainID) s.Require().Equal(chainConfig.ProxyAddress, proxyAddress) - // add managed cellar + ////////////////// + // Add a cellar // + ////////////////// + s.T().Log("Creating AddAxelarManagedCellarIDsProposal for counter contract") addAxelarManagedCellarIDsProp := types.AddAxelarManagedCellarIDsProposal{ Title: "add the counter contract as axelar cellar", @@ -123,6 +125,10 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Len(cellarIDsResponse.CellarIds, 1) s.Require().Equal(cellarIDsResponse.CellarIds[0], counterContract.Hex()) + ///////////////////////////// + // Schedule an Axelar cork // + ///////////////////////////// + s.T().Log("Schedule an axelar cork for the future") node, err := proposerCtx.GetNode() s.Require().NoError(err) @@ -234,10 +240,15 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().True(sdk.MustNewDecFromStr(corkResultResponse.CorkResult.ApprovalPercentage).GT(corkVoteThreshold)) s.Require().Equal(counterContract, common.HexToAddress(corkResultResponse.CorkResult.Cork.TargetContractAddress)) + // the corks are deleted when it's converted into a WinningAxelarCork and is relayable s.T().Log("Verifying scheduled axelar corks were deleted") scheduledCorksByHeightResponse, err := axelarcorkQueryClient.QueryScheduledCorksByBlockHeight(context.Background(), &types.QueryScheduledCorksByBlockHeightRequest{BlockHeight: targetBlockHeight, ChainId: arbitrumChainID}) s.Require().NoError(err) - s.Require().Len(scheduledCorksByHeightResponse.Corks, 0) + s.Require().Empty(scheduledCorksByHeightResponse.Corks) + + /////////////////////////////////////////////// + // Create a governance scheduled Axelar cork // + /////////////////////////////////////////////// protoJSON := "{\"cellar_id\":\"0x123801a7D398351b8bE11C439e05C5B3259aeC9B\",\"cellar_v1\":{\"some_fuction\":{\"function_args\":{}},\"block_height\":12345}}" s.T().Log("Creating AxelarScheduledCorkProposal for counter contract") @@ -280,6 +291,10 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().Equal(propContent.Deadline, addAxelarScheduledCorkProp.Deadline) propID++ + ////////////////////////////////////// + // Upgrade an Axelar proxy contract // + ////////////////////////////////////// + s.T().Log("Creating UpgradeAxelarProxyContractProposal") newProxyAddress := "0x438087f7c226A89762a791F187d7c3D4a0e95ae6" upgradeAxelarProxyContractProp := types.UpgradeAxelarProxyContractProposal{ @@ -302,7 +317,7 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err, "Unable to create UpgradeAxelarProxyContractProposal") s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, upgradeAxelarProxyContractPropMsg) - //propID++ + propID++ s.T().Log("Verifying upgrade data added correctly") node, err = val0ClientCtx.GetNode() @@ -324,9 +339,102 @@ func (s *IntegrationTestSuite) TestAxelarCork() { s.Require().NoError(err) s.Require().Equal(encodedProxy, newProxyAddress) - // cancel proxy upgrade - // remove managed cellar - // remove chain configuration + ///////////////////////////////////////////// + // Cancel an Axelar proxy contract upgrade // + ///////////////////////////////////////////// + + s.T().Log("Creating CancelAxelarProxyContractUpgradeProposal") + cancelAxelarProxyContractUpgradeProp := types.CancelAxelarProxyContractUpgradeProposal{ + Title: "cancel upgrade ofan axelar proxy contract", + Description: "arbitrum is not getting a new proxy", + ChainId: arbitrumChainID, + } + + cancelAxelarProxyContractUpgradePropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &cancelAxelarProxyContractUpgradeProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create CancelAxelarProxyContractUpgradeProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, cancelAxelarProxyContractUpgradePropMsg) + propID++ + + s.T().Log("Verifying upgrade data removed correctly") + upgradeResponse, err = axelarcorkQueryClient.QueryAxelarProxyUpgradeData(context.Background(), &types.QueryAxelarProxyUpgradeDataRequest{}) + s.Require().NoError(err) + s.Require().Empty(upgradeResponse.ProxyUpgradeData) + + ///////////////////// + // Remove a cellar // + ///////////////////// + + s.T().Log("Creating RemoveAxelarManagedCellarIDsProposal for counter contract") + removeAxelarManagedCellarIDsProp := types.RemoveAxelarManagedCellarIDsProposal{ + Title: "add the counter contract as axelar cellar", + Description: "arbitrum counter contract", + ChainId: arbitrumChainID, + CellarIds: &types.CellarIDSet{ + Ids: []string{ + counterContract.Hex(), + }, + }, + } + + removeAxelarManagedCellarIDsPropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &removeAxelarManagedCellarIDsProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create RemoveAxelarManagedCellarIDsProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, removeAxelarManagedCellarIDsPropMsg) + propID++ + + s.T().Log("Verifying CellarID correctly added") + cellarIDsResponse, err = axelarcorkQueryClient.QueryCellarIDsByChainID(context.Background(), &types.QueryCellarIDsByChainIDRequest{ChainId: arbitrumChainID}) + s.Require().NoError(err) + s.Require().Empty(cellarIDsResponse.CellarIds) + + ////////////////////////////////// + // Remove a chain configuration // + ////////////////////////////////// + + s.T().Log("Creating RemoveChainConfigurationProposal") + removeChainConfigurationProp := types.RemoveChainConfigurationProposal{ + Title: "add a chain configuration", + Description: "adding an arbitrum chain config", + ChainId: arbitrumChainID, + } + + removeChainConfigurationPropMsg, err := govtypesv1beta1.NewMsgSubmitProposal( + &removeChainConfigurationProp, + sdk.Coins{ + { + Denom: testDenom, + Amount: math.NewInt(2), + }, + }, + proposer.address(), + ) + s.Require().NoError(err, "Unable to create RemoveChainConfigurationProposal") + + s.submitAndVoteForAxelarProposal(proposerCtx, orch0ClientCtx, propID, removeChainConfigurationPropMsg) + + s.T().Log("Verifying ChainConfiguration correctly added") + chainConfigurationsResponse, err = axelarcorkQueryClient.QueryChainConfigurations(context.Background(), &types.QueryChainConfigurationsRequest{}) + s.Require().NoError(err) + s.Require().Empty(chainConfigurationsResponse.Configurations) }) }