diff --git a/docs/docs/03-light-clients/04-wasm/07-contracts.md b/docs/docs/03-light-clients/04-wasm/07-contracts.md index f018e2ab96d..fc46344444f 100644 --- a/docs/docs/03-light-clients/04-wasm/07-contracts.md +++ b/docs/docs/03-light-clients/04-wasm/07-contracts.md @@ -15,12 +15,13 @@ The `08-wasm` light client proxy performs calls to the Wasm light client via the ## `InstantiateMessage` -This is the message sent to the contract's `instantiate` entry point. It contains the client and consensus state provided in [`MsgCreateClient`](https://github.com/cosmos/ibc-go/blob/v7.2.0/proto/ibc/core/client/v1/tx.proto#L25-L37). +This is the message sent to the contract's `instantiate` entry point. It contains the bytes of the protobuf-encoded client and consensus states of the underlying light client, both provided in [`MsgCreateClient`](https://github.com/cosmos/ibc-go/blob/v7.2.0/proto/ibc/core/client/v1/tx.proto#L25-L37). Please note that the bytes contained within the JSON message are represented as base64-encoded strings. ```go type InstantiateMessage struct { - ClientState *ClientState `json:"client_state"` - ConsensusState *ConsensusState `json:"consensus_state"` + ClientState []byte `json:"client_state"` + ConsensusState []byte `json:"consensus_state"` + Checksum []byte `json:"checksum" } ``` diff --git a/e2e/tests/wasm/contracts/ics10_grandpa_cw.wasm b/e2e/tests/wasm/contracts/ics10_grandpa_cw.wasm deleted file mode 100755 index cccae7aeeaf..00000000000 Binary files a/e2e/tests/wasm/contracts/ics10_grandpa_cw.wasm and /dev/null differ diff --git a/e2e/tests/wasm/contracts/ics10_grandpa_cw.wasm.gz b/e2e/tests/wasm/contracts/ics10_grandpa_cw.wasm.gz new file mode 100644 index 00000000000..b6fd71c404f Binary files /dev/null and b/e2e/tests/wasm/contracts/ics10_grandpa_cw.wasm.gz differ diff --git a/e2e/tests/wasm/contracts/ics10_grandpa_cw_expiry.wasm.gz b/e2e/tests/wasm/contracts/ics10_grandpa_cw_expiry.wasm.gz index b5e0d7a6a8a..0bb1e39a2b2 100644 Binary files a/e2e/tests/wasm/contracts/ics10_grandpa_cw_expiry.wasm.gz and b/e2e/tests/wasm/contracts/ics10_grandpa_cw_expiry.wasm.gz differ diff --git a/e2e/tests/wasm/grandpa_test.go b/e2e/tests/wasm/grandpa_test.go index 9c559871816..cae0a260872 100644 --- a/e2e/tests/wasm/grandpa_test.go +++ b/e2e/tests/wasm/grandpa_test.go @@ -89,7 +89,7 @@ func (s *GrandpaTestSuite) TestMsgTransfer_Succeeds_GrandpaContract() { cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - file, err := os.Open("contracts/ics10_grandpa_cw.wasm") + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") s.Require().NoError(err) checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) @@ -241,7 +241,7 @@ func (s *GrandpaTestSuite) TestMsgTransfer_TimesOut_GrandpaContract() { cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - file, err := os.Open("contracts/ics10_grandpa_cw.wasm") + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") s.Require().NoError(err) checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) @@ -355,7 +355,7 @@ func (s *GrandpaTestSuite) TestMsgMigrateContract_Success_GrandpaContract() { cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - file, err := os.Open("contracts/ics10_grandpa_cw.wasm") + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") s.Require().NoError(err) checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) @@ -442,7 +442,7 @@ func (s *GrandpaTestSuite) TestMsgMigrateContract_ContractError_GrandpaContract( cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - file, err := os.Open("contracts/ics10_grandpa_cw.wasm") + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") s.Require().NoError(err) checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) diff --git a/modules/light-clients/08-wasm/keeper/keeper_test.go b/modules/light-clients/08-wasm/keeper/keeper_test.go index 1e633d5e124..e50b813992e 100644 --- a/modules/light-clients/08-wasm/keeper/keeper_test.go +++ b/modules/light-clients/08-wasm/keeper/keeper_test.go @@ -89,8 +89,15 @@ func (suite *KeeperTestSuite) setupWasmWithMockVM() (ibctesting.TestingApp, map[ err := json.Unmarshal(initMsg, &payload) suite.Require().NoError(err) - store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState)) - store.Set(host.ConsensusStateKey(payload.ClientState.LatestHeight), clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), payload.ConsensusState)) + wrappedClientState := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState) + + clientState := types.NewClientState(payload.ClientState, payload.Checksum, wrappedClientState.GetLatestHeight().(clienttypes.Height)) + clientStateBz := clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState) + store.Set(host.ClientStateKey(), clientStateBz) + + consensusState := types.NewConsensusState(payload.ConsensusState) + consensusStateBz := clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), consensusState) + store.Set(host.ConsensusStateKey(clientState.GetLatestHeight()), consensusStateBz) resp, err := json.Marshal(types.EmptyResult{}) suite.Require().NoError(err) diff --git a/modules/light-clients/08-wasm/keeper/msg_server_test.go b/modules/light-clients/08-wasm/keeper/msg_server_test.go index 268564ceeb0..ad2b2dce326 100644 --- a/modules/light-clients/08-wasm/keeper/msg_server_test.go +++ b/modules/light-clients/08-wasm/keeper/msg_server_test.go @@ -175,8 +175,9 @@ func (suite *KeeperTestSuite) TestMsgMigrateContract() { suite.mockVM.MigrateFn = func(_ wasmvm.Checksum, _ wasmvmtypes.Env, _ []byte, store wasmvm.KVStore, _ wasmvm.GoAPI, _ wasmvm.Querier, _ wasmvm.GasMeter, _ uint64, _ wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { // the checksum written in the client state will later be overwritten by the message server. - expClientState = types.NewClientState([]byte{1}, []byte("invalid checksum"), clienttypes.NewHeight(2000, 2)) - store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), expClientState)) + expClientStateBz := wasmtesting.CreateMockClientStateBz(suite.chainA.App.AppCodec(), []byte("invalid checksum")) + expClientState = clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), expClientStateBz).(*types.ClientState) + store.Set(host.ClientStateKey(), expClientStateBz) data, err := json.Marshal(types.EmptyResult{}) suite.Require().NoError(err) diff --git a/modules/light-clients/08-wasm/testing/values.go b/modules/light-clients/08-wasm/testing/values.go index 968c62b0b21..e91fa5296a1 100644 --- a/modules/light-clients/08-wasm/testing/values.go +++ b/modules/light-clients/08-wasm/testing/values.go @@ -2,33 +2,54 @@ package testing import ( "errors" + "time" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + testing "github.com/cosmos/ibc-go/v8/testing" ) var ( // Represents the code of the wasm contract used in the tests with a mock vm. - WasmMagicNumber = []byte("\x00\x61\x73\x6D") - Code = append(WasmMagicNumber, []byte("0123456780123456780123456780")...) - contractClientState = []byte{1} - contractConsensusState = []byte{2} - MockClientStateBz = []byte("client-state-data") - MockConsensusStateBz = []byte("consensus-state-data") - MockValidProofBz = []byte("valid proof") - MockInvalidProofBz = []byte("invalid proof") - MockUpgradedClientStateProofBz = []byte("upgraded client state proof") - MockUpgradedConsensusStateProofBz = []byte("upgraded consensus state proof") + WasmMagicNumber = []byte("\x00\x61\x73\x6D") + Code = append(WasmMagicNumber, []byte("0123456780123456780123456780")...) + MockClientStateBz = []byte("client-state-data") + MockConsensusStateBz = []byte("consensus-state-data") + MockTendermitClientState = CreateMockTendermintClientState(clienttypes.NewHeight(1, 10)) + MockTendermintClientHeader = &ibctm.Header{} + MockTendermintClientMisbehaviour = ibctm.NewMisbehaviour("client-id", MockTendermintClientHeader, MockTendermintClientHeader) + MockTendermintClientConsensusState = ibctm.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash")), []byte("nextValsHash")) + MockValidProofBz = []byte("valid proof") + MockInvalidProofBz = []byte("invalid proof") + MockUpgradedClientStateProofBz = []byte("upgraded client state proof") + MockUpgradedConsensusStateProofBz = []byte("upgraded consensus state proof") ErrMockContract = errors.New("mock contract error") ErrMockVM = errors.New("mock vm error") ) +// CreateMockTendermintClientState returns a valid Tendermint client state for use in tests. +func CreateMockTendermintClientState(height clienttypes.Height) *ibctm.ClientState { + return ibctm.NewClientState( + "chain-id", + ibctm.DefaultTrustLevel, + testing.TrustingPeriod, + testing.UnbondingPeriod, + testing.MaxClockDrift, + height, + commitmenttypes.GetSDKSpecs(), + testing.UpgradePath, + ) +} + // CreateMockClientStateBz returns valid client state bytes for use in tests. func CreateMockClientStateBz(cdc codec.BinaryCodec, checksum types.Checksum) []byte { - mockClientSate := types.NewClientState([]byte{1}, checksum, clienttypes.NewHeight(2000, 2)) + wrappedClientStateBz := clienttypes.MustMarshalClientState(cdc, MockTendermitClientState) + mockClientSate := types.NewClientState(wrappedClientStateBz, checksum, MockTendermitClientState.GetLatestHeight().(clienttypes.Height)) return clienttypes.MustMarshalClientState(cdc, mockClientSate) } diff --git a/modules/light-clients/08-wasm/testing/wasm_endpoint.go b/modules/light-clients/08-wasm/testing/wasm_endpoint.go index 5b0af1705b5..6d126ea35c9 100644 --- a/modules/light-clients/08-wasm/testing/wasm_endpoint.go +++ b/modules/light-clients/08-wasm/testing/wasm_endpoint.go @@ -29,8 +29,11 @@ func (endpoint *WasmEndpoint) CreateClient() error { checksum, err := types.CreateChecksum(Code) require.NoError(endpoint.Chain.TB, err) - clientState := types.NewClientState(contractClientState, checksum, clienttypes.NewHeight(0, 1)) - consensusState := types.NewConsensusState(contractConsensusState) + wrappedClientStateBz := clienttypes.MustMarshalClientState(endpoint.Chain.App.AppCodec(), CreateMockTendermintClientState(clienttypes.NewHeight(1, 5))) + wrappedClientConsensusStateBz := clienttypes.MustMarshalConsensusState(endpoint.Chain.App.AppCodec(), MockTendermintClientConsensusState) + + clientState := types.NewClientState(wrappedClientStateBz, checksum, clienttypes.NewHeight(0, 1)) + consensusState := types.NewConsensusState(wrappedClientConsensusStateBz) msg, err := clienttypes.NewMsgCreateClient( clientState, consensusState, endpoint.Chain.SenderAccount.GetAddress().String(), diff --git a/modules/light-clients/08-wasm/types/client_state.go b/modules/light-clients/08-wasm/types/client_state.go index 365dc327467..095cfa31096 100644 --- a/modules/light-clients/08-wasm/types/client_state.go +++ b/modules/light-clients/08-wasm/types/client_state.go @@ -121,8 +121,9 @@ func (cs ClientState) Initialize(ctx sdk.Context, cdc codec.BinaryCodec, clientS } payload := InstantiateMessage{ - ClientState: &cs, - ConsensusState: consensusState, + ClientState: cs.Data, + ConsensusState: consensusState.Data, + Checksum: cs.Checksum, } return wasmInstantiate(ctx, cdc, clientStore, &cs, payload) diff --git a/modules/light-clients/08-wasm/types/client_state_test.go b/modules/light-clients/08-wasm/types/client_state_test.go index 2136ca22aa6..b2da5984a31 100644 --- a/modules/light-clients/08-wasm/types/client_state_test.go +++ b/modules/light-clients/08-wasm/types/client_state_test.go @@ -257,8 +257,15 @@ func (suite *TypesTestSuite) TestInitialize() { suite.Require().Equal(env.Contract.Address, defaultWasmClientID) - store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState)) - store.Set(host.ConsensusStateKey(payload.ClientState.LatestHeight), clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), payload.ConsensusState)) + wrappedClientState := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState) + + clientState := types.NewClientState(payload.ClientState, payload.Checksum, wrappedClientState.GetLatestHeight().(clienttypes.Height)) + clientStateBz := clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState) + store.Set(host.ClientStateKey(), clientStateBz) + + consensusState := types.NewConsensusState(payload.ConsensusState) + consensusStateBz := clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), consensusState) + store.Set(host.ConsensusStateKey(clientState.GetLatestHeight()), consensusStateBz) resp, err := json.Marshal(types.EmptyResult{}) suite.Require().NoError(err) @@ -305,18 +312,17 @@ func (suite *TypesTestSuite) TestInitialize() { suite.Run(tc.name, func() { suite.SetupWasmWithMockVM() - checksum, err := types.CreateChecksum(wasmtesting.Code) - suite.Require().NoError(err) - - clientState = types.NewClientState([]byte{1}, checksum, clienttypes.NewHeight(0, 1)) - consensusState = types.NewConsensusState([]byte{2}) + wrappedClientStateBz := clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), wasmtesting.MockTendermitClientState) + wrappedClientConsensusStateBz := clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientConsensusState) + clientState = types.NewClientState(wrappedClientStateBz, suite.checksum, wasmtesting.MockTendermitClientState.GetLatestHeight().(clienttypes.Height)) + consensusState = types.NewConsensusState(wrappedClientConsensusStateBz) clientID := suite.chainA.App.GetIBCKeeper().ClientKeeper.GenerateClientIdentifier(suite.chainA.GetContext(), clientState.ClientType()) clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID) tc.malleate() - err = clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, clientStore, consensusState) + err := clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, clientStore, consensusState) expPass := tc.expError == nil if expPass { diff --git a/modules/light-clients/08-wasm/types/contract_api.go b/modules/light-clients/08-wasm/types/contract_api.go index 888eacd860e..20b39c3f0d8 100644 --- a/modules/light-clients/08-wasm/types/contract_api.go +++ b/modules/light-clients/08-wasm/types/contract_api.go @@ -7,8 +7,9 @@ import ( // InstantiateMessage is the message that is sent to the contract's instantiate entry point. type InstantiateMessage struct { - ClientState *ClientState `json:"client_state"` - ConsensusState *ConsensusState `json:"consensus_state"` + ClientState []byte `json:"client_state"` + ConsensusState []byte `json:"consensus_state"` + Checksum []byte `json:"checksum"` } // QueryMsg is used to encode messages that are sent to the contract's query entry point. @@ -36,12 +37,12 @@ type TimestampAtHeightMsg struct { // VerifyClientMessageMsg is a queryMsg sent to the contract to verify a client message. type VerifyClientMessageMsg struct { - ClientMessage *ClientMessage `json:"client_message"` + ClientMessage []byte `json:"client_message"` } // CheckForMisbehaviourMsg is a queryMsg sent to the contract to check for misbehaviour. type CheckForMisbehaviourMsg struct { - ClientMessage *ClientMessage `json:"client_message"` + ClientMessage []byte `json:"client_message"` } // SudoMsg is used to encode messages that are sent to the contract's sudo entry point. @@ -59,12 +60,12 @@ type SudoMsg struct { // UpdateStateMsg is a sudoMsg sent to the contract to update the client state. type UpdateStateMsg struct { - ClientMessage *ClientMessage `json:"client_message"` + ClientMessage []byte `json:"client_message"` } // UpdateStateOnMisbehaviourMsg is a sudoMsg sent to the contract to update its state on misbehaviour. type UpdateStateOnMisbehaviourMsg struct { - ClientMessage *ClientMessage `json:"client_message"` + ClientMessage []byte `json:"client_message"` } // VerifyMembershipMsg is a sudoMsg sent to the contract to verify a membership proof. @@ -88,10 +89,10 @@ type VerifyNonMembershipMsg struct { // VerifyUpgradeAndUpdateStateMsg is a sudoMsg sent to the contract to verify an upgrade and update its state. type VerifyUpgradeAndUpdateStateMsg struct { - UpgradeClientState ClientState `json:"upgrade_client_state"` - UpgradeConsensusState ConsensusState `json:"upgrade_consensus_state"` - ProofUpgradeClient []byte `json:"proof_upgrade_client"` - ProofUpgradeConsensusState []byte `json:"proof_upgrade_consensus_state"` + UpgradeClientState []byte `json:"upgrade_client_state"` + UpgradeConsensusState []byte `json:"upgrade_consensus_state"` + ProofUpgradeClient []byte `json:"proof_upgrade_client"` + ProofUpgradeConsensusState []byte `json:"proof_upgrade_consensus_state"` } // MigrateClientStore is a sudoMsg sent to the contract to verify a given substitute client and update to its state. diff --git a/modules/light-clients/08-wasm/types/misbehaviour_handle.go b/modules/light-clients/08-wasm/types/misbehaviour_handle.go index 16a234b44b8..3923287d523 100644 --- a/modules/light-clients/08-wasm/types/misbehaviour_handle.go +++ b/modules/light-clients/08-wasm/types/misbehaviour_handle.go @@ -18,7 +18,7 @@ func (cs ClientState) CheckForMisbehaviour(ctx sdk.Context, _ codec.BinaryCodec, } payload := QueryMsg{ - CheckForMisbehaviour: &CheckForMisbehaviourMsg{ClientMessage: clientMessage}, + CheckForMisbehaviour: &CheckForMisbehaviourMsg{ClientMessage: clientMessage.Data}, } result, err := wasmQuery[CheckForMisbehaviourResult](ctx, clientStore, &cs, payload) diff --git a/modules/light-clients/08-wasm/types/misbehaviour_handle_test.go b/modules/light-clients/08-wasm/types/misbehaviour_handle_test.go index 13f4489c742..05fd12e7566 100644 --- a/modules/light-clients/08-wasm/types/misbehaviour_handle_test.go +++ b/modules/light-clients/08-wasm/types/misbehaviour_handle_test.go @@ -9,8 +9,9 @@ import ( wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing" "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/cosmos/ibc-go/v8/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ) func (suite *TypesTestSuite) TestCheckForMisbehaviour() { @@ -61,7 +62,7 @@ func (suite *TypesTestSuite) TestCheckForMisbehaviour() { }, { "success: invalid client message", func() { - clientMessage = &ibctmtypes.Header{} + clientMessage = &ibctm.Header{} // we will not register the callback here because this test case does not reach the VM }, false, @@ -78,7 +79,7 @@ func (suite *TypesTestSuite) TestCheckForMisbehaviour() { clientState := endpoint.GetClientState() clientMessage = &types.ClientMessage{ - Data: []byte{1}, + Data: clienttypes.MustMarshalClientMessage(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientMisbehaviour), } clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), endpoint.ClientID) diff --git a/modules/light-clients/08-wasm/types/proposal_handle_test.go b/modules/light-clients/08-wasm/types/proposal_handle_test.go index 812dd501f1b..7e4ba10aa96 100644 --- a/modules/light-clients/08-wasm/types/proposal_handle_test.go +++ b/modules/light-clients/08-wasm/types/proposal_handle_test.go @@ -6,10 +6,6 @@ import ( cosmwasm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" - storetypes "cosmossdk.io/store/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing" "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -130,13 +126,3 @@ func (suite *TypesTestSuite) TestCheckSubstituteAndUpdateState() { }) } } - -func GetProcessedHeight(clientStore storetypes.KVStore, height exported.Height) (uint64, bool) { - key := ibctm.ProcessedHeightKey(height) - bz := clientStore.Get(key) - if len(bz) == 0 { - return 0, false - } - - return sdk.BigEndianToUint64(bz), true -} diff --git a/modules/light-clients/08-wasm/types/types_test.go b/modules/light-clients/08-wasm/types/types_test.go index 8f882f64aaa..e1729f66997 100644 --- a/modules/light-clients/08-wasm/types/types_test.go +++ b/modules/light-clients/08-wasm/types/types_test.go @@ -89,8 +89,15 @@ func (suite *TypesTestSuite) setupWasmWithMockVM() (ibctesting.TestingApp, map[s err := json.Unmarshal(initMsg, &payload) suite.Require().NoError(err) - store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState)) - store.Set(host.ConsensusStateKey(payload.ClientState.LatestHeight), clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), payload.ConsensusState)) + wrappedClientState := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState) + + clientState := types.NewClientState(payload.ClientState, payload.Checksum, wrappedClientState.GetLatestHeight().(clienttypes.Height)) + clientStateBz := clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState) + store.Set(host.ClientStateKey(), clientStateBz) + + consensusState := types.NewConsensusState(payload.ConsensusState) + consensusStateBz := clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), consensusState) + store.Set(host.ConsensusStateKey(clientState.GetLatestHeight()), consensusStateBz) resp, err := json.Marshal(types.EmptyResult{}) suite.Require().NoError(err) diff --git a/modules/light-clients/08-wasm/types/update.go b/modules/light-clients/08-wasm/types/update.go index 0c640655bcf..20d2bfb8e4a 100644 --- a/modules/light-clients/08-wasm/types/update.go +++ b/modules/light-clients/08-wasm/types/update.go @@ -26,7 +26,7 @@ func (cs ClientState) VerifyClientMessage(ctx sdk.Context, _ codec.BinaryCodec, } payload := QueryMsg{ - VerifyClientMessage: &VerifyClientMessageMsg{ClientMessage: clientMessage}, + VerifyClientMessage: &VerifyClientMessageMsg{ClientMessage: clientMessage.Data}, } _, err := wasmQuery[EmptyResult](ctx, clientStore, &cs, payload) return err @@ -40,7 +40,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client } payload := SudoMsg{ - UpdateState: &UpdateStateMsg{ClientMessage: clientMessage}, + UpdateState: &UpdateStateMsg{ClientMessage: clientMessage.Data}, } result, err := wasmSudo[UpdateStateResult](ctx, cdc, clientStore, &cs, payload) @@ -65,7 +65,7 @@ func (cs ClientState) UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.Binar } payload := SudoMsg{ - UpdateStateOnMisbehaviour: &UpdateStateOnMisbehaviourMsg{ClientMessage: clientMessage}, + UpdateStateOnMisbehaviour: &UpdateStateOnMisbehaviourMsg{ClientMessage: clientMessage.Data}, } _, err := wasmSudo[EmptyResult](ctx, cdc, clientStore, &cs, payload) diff --git a/modules/light-clients/08-wasm/types/update_test.go b/modules/light-clients/08-wasm/types/update_test.go index c4f08707fef..b1e4a4a9525 100644 --- a/modules/light-clients/08-wasm/types/update_test.go +++ b/modules/light-clients/08-wasm/types/update_test.go @@ -15,12 +15,12 @@ import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/cosmos/ibc-go/v8/modules/core/exported" - cmttypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) func (suite *TypesTestSuite) TestUpdateState() { - mockHeight := clienttypes.NewHeight(1, 1) + mockHeight := clienttypes.NewHeight(1, 50) var ( clientMsg exported.ClientMessage @@ -44,7 +44,7 @@ func (suite *TypesTestSuite) TestUpdateState() { suite.Require().NotNil(msg.UpdateState) suite.Require().NotNil(msg.UpdateState.ClientMessage) - suite.Require().Equal(msg.UpdateState.ClientMessage.Data, wasmtesting.CreateMockClientStateBz(suite.chainA.Codec, suite.checksum)) + suite.Require().Equal(msg.UpdateState.ClientMessage, clienttypes.MustMarshalClientMessage(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientHeader)) suite.Require().Nil(msg.VerifyMembership) suite.Require().Nil(msg.VerifyNonMembership) suite.Require().Nil(msg.UpdateStateOnMisbehaviour) @@ -80,7 +80,7 @@ func (suite *TypesTestSuite) TestUpdateState() { bz := store.Get(host.ClientStateKey()) suite.Require().NotEmpty(bz) clientState := clienttypes.MustUnmarshalClientState(suite.chainA.Codec, bz).(*types.ClientState) - clientState.Data = msg.UpdateState.ClientMessage.Data + clientState.LatestHeight = mockHeight expectedClientStateBz = clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState) store.Set(host.ClientStateKey(), expectedClientStateBz) @@ -113,9 +113,9 @@ func (suite *TypesTestSuite) TestUpdateState() { "failure: invalid ClientMessage type", func() { // SudoCallback left nil because clientMsg is checked by 08-wasm before callbackFn is called. - clientMsg = &cmttypes.Misbehaviour{} + clientMsg = &ibctm.Misbehaviour{} }, - fmt.Errorf("expected type %T, got %T", (*types.ClientMessage)(nil), (*cmttypes.Misbehaviour)(nil)), + fmt.Errorf("expected type %T, got %T", (*types.ClientMessage)(nil), (*ibctm.Misbehaviour)(nil)), nil, }, { @@ -136,7 +136,7 @@ func (suite *TypesTestSuite) TestUpdateState() { expectedClientStateBz = nil clientMsg = &types.ClientMessage{ - Data: wasmtesting.CreateMockClientStateBz(suite.chainA.Codec, suite.checksum), + Data: clienttypes.MustMarshalClientMessage(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientHeader), } endpoint := wasmtesting.NewWasmEndpoint(suite.chainA) @@ -169,6 +169,8 @@ func (suite *TypesTestSuite) TestUpdateState() { } func (suite *TypesTestSuite) TestUpdateStateOnMisbehaviour() { + mockHeight := clienttypes.NewHeight(1, 50) + var clientMsg exported.ClientMessage var expectedClientStateBz []byte @@ -218,8 +220,13 @@ func (suite *TypesTestSuite) TestUpdateStateOnMisbehaviour() { suite.Require().NoError(err) // set new client state in store - expectedClientStateBz = msg.UpdateStateOnMisbehaviour.ClientMessage.Data + bz := store.Get(host.ClientStateKey()) + suite.Require().NotEmpty(bz) + clientState := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), bz).(*types.ClientState) + clientState.LatestHeight = mockHeight + expectedClientStateBz = clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState) store.Set(host.ClientStateKey(), expectedClientStateBz) + resp, err := json.Marshal(types.EmptyResult{}) if err != nil { return nil, 0, err @@ -229,15 +236,15 @@ func (suite *TypesTestSuite) TestUpdateStateOnMisbehaviour() { }) }, nil, - wasmtesting.MockClientStateBz, + clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), wasmtesting.CreateMockTendermintClientState(mockHeight)), }, { "failure: invalid client message", func() { - clientMsg = &cmttypes.Header{} + clientMsg = &ibctm.Header{} // we will not register the callback here because this test case does not reach the VM }, - fmt.Errorf("expected type %T, got %T", (*types.ClientMessage)(nil), (*cmttypes.Header)(nil)), + fmt.Errorf("expected type %T, got %T", (*types.ClientMessage)(nil), (*ibctm.Header)(nil)), nil, }, { @@ -264,7 +271,7 @@ func (suite *TypesTestSuite) TestUpdateStateOnMisbehaviour() { store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), endpoint.ClientID) clientMsg = &types.ClientMessage{ - Data: wasmtesting.CreateMockClientStateBz(suite.chainA.Codec, suite.checksum), + Data: clienttypes.MustMarshalClientMessage(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientMisbehaviour), } clientState := endpoint.GetClientState() diff --git a/modules/light-clients/08-wasm/types/upgrade.go b/modules/light-clients/08-wasm/types/upgrade.go index aacc0c2ee7b..3addb071d54 100644 --- a/modules/light-clients/08-wasm/types/upgrade.go +++ b/modules/light-clients/08-wasm/types/upgrade.go @@ -36,8 +36,8 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( payload := SudoMsg{ VerifyUpgradeAndUpdateState: &VerifyUpgradeAndUpdateStateMsg{ - UpgradeClientState: *wasmUpgradeClientState, - UpgradeConsensusState: *wasmUpgradeConsState, + UpgradeClientState: wasmUpgradeClientState.Data, + UpgradeConsensusState: wasmUpgradeConsState.Data, ProofUpgradeClient: proofUpgradeClient, ProofUpgradeConsensusState: proofUpgradeConsState, }, diff --git a/modules/light-clients/08-wasm/types/upgrade_test.go b/modules/light-clients/08-wasm/types/upgrade_test.go index b77efcfe5cb..6006066ecc7 100644 --- a/modules/light-clients/08-wasm/types/upgrade_test.go +++ b/modules/light-clients/08-wasm/types/upgrade_test.go @@ -2,6 +2,7 @@ package types_test import ( "encoding/json" + "time" wasmvm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" @@ -11,11 +12,12 @@ import ( wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing" "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" "github.com/cosmos/ibc-go/v8/modules/core/exported" solomachine "github.com/cosmos/ibc-go/v8/modules/light-clients/06-solomachine" - ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -66,7 +68,7 @@ func (suite *TypesTestSuite) TestVerifyClientMessage() { { "failure: invalid client message", func() { - clientMsg = &ibctmtypes.Header{} + clientMsg = &ibctm.Header{} suite.mockVM.RegisterQueryCallback(types.VerifyClientMessageMsg{}, func(_ wasmvm.Checksum, _ wasmvmtypes.Env, queryMsg []byte, _ wasmvm.KVStore, _ wasmvm.GoAPI, _ wasmvm.Querier, _ wasmvm.GasMeter, _ uint64, _ wasmvmtypes.UFraction) ([]byte, uint64, error) { resp, err := json.Marshal(types.EmptyResult{}) @@ -101,7 +103,7 @@ func (suite *TypesTestSuite) TestVerifyClientMessage() { clientState := endpoint.GetClientState() clientMsg = &types.ClientMessage{ - Data: []byte{1}, + Data: clienttypes.MustMarshalClientMessage(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientHeader), } tc.malleate() @@ -140,9 +142,14 @@ func (suite *TypesTestSuite) TestVerifyUpgradeAndUpdateState() { err := json.Unmarshal(sudoMsg, &payload) suite.Require().NoError(err) + expectedUpgradedClient, ok := upgradedClient.(*types.ClientState) + suite.Require().True(ok) + expectedUpgradedConsensus, ok := upgradedConsState.(*types.ConsensusState) + suite.Require().True(ok) + // verify payload values - suite.Require().Equal(upgradedClient, &payload.VerifyUpgradeAndUpdateState.UpgradeClientState) - suite.Require().Equal(upgradedConsState, &payload.VerifyUpgradeAndUpdateState.UpgradeConsensusState) + suite.Require().Equal(expectedUpgradedClient.Data, payload.VerifyUpgradeAndUpdateState.UpgradeClientState) + suite.Require().Equal(expectedUpgradedConsensus.Data, payload.VerifyUpgradeAndUpdateState.UpgradeConsensusState) suite.Require().Equal(proofUpgradedClient, payload.VerifyUpgradeAndUpdateState.ProofUpgradeClient) suite.Require().Equal(proofUpgradedConsState, payload.VerifyUpgradeAndUpdateState.ProofUpgradeConsensusState) @@ -156,8 +163,9 @@ func (suite *TypesTestSuite) TestVerifyUpgradeAndUpdateState() { suite.Require().NoError(err) // set new client state and consensus state + wrappedUpgradedClient := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), expectedUpgradedClient.Data) store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), upgradedClient)) - store.Set(host.ConsensusStateKey(upgradedClient.GetLatestHeight()), clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState)) + store.Set(host.ConsensusStateKey(wrappedUpgradedClient.GetLatestHeight()), clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState)) return &wasmvmtypes.Response{Data: data}, wasmtesting.DefaultGasUsed, nil }) @@ -202,8 +210,14 @@ func (suite *TypesTestSuite) TestVerifyUpgradeAndUpdateState() { clientState := endpoint.GetClientState().(*types.ClientState) - upgradedClient = types.NewClientState(wasmtesting.MockClientStateBz, clientState.Checksum, clienttypes.NewHeight(0, clientState.GetLatestHeight().GetRevisionHeight()+1)) - upgradedConsState = &types.ConsensusState{wasmtesting.MockConsensusStateBz} + newLatestHeight := clienttypes.NewHeight(2, 10) + wrappedUpgradedClient := wasmtesting.CreateMockTendermintClientState(newLatestHeight) + wrappedUpgradedClientBz := clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), wrappedUpgradedClient) + upgradedClient = types.NewClientState(wrappedUpgradedClientBz, clientState.Checksum, newLatestHeight) + + wrappedUpgradedConsensus := ibctm.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("new-hash")), []byte("new-nextValsHash")) + wrappedUpgradedConsensusBz := clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), wrappedUpgradedConsensus) + upgradedConsState = types.NewConsensusState(wrappedUpgradedConsensusBz) tc.malleate() diff --git a/modules/light-clients/08-wasm/types/vm_test.go b/modules/light-clients/08-wasm/types/vm_test.go index bc1eed6ffdc..7b56857a55e 100644 --- a/modules/light-clients/08-wasm/types/vm_test.go +++ b/modules/light-clients/08-wasm/types/vm_test.go @@ -32,8 +32,15 @@ func (suite *TypesTestSuite) TestWasmInstantiate() { err := json.Unmarshal(initMsg, &payload) suite.Require().NoError(err) - store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState)) - store.Set(host.ConsensusStateKey(payload.ClientState.LatestHeight), clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), payload.ConsensusState)) + wrappedClientState := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState) + + clientState := types.NewClientState(payload.ClientState, payload.Checksum, wrappedClientState.GetLatestHeight().(clienttypes.Height)) + clientStateBz := clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState) + store.Set(host.ClientStateKey(), clientStateBz) + + consensusState := types.NewConsensusState(payload.ConsensusState) + consensusStateBz := clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), consensusState) + store.Set(host.ConsensusStateKey(clientState.GetLatestHeight()), consensusStateBz) return &wasmvmtypes.Response{}, 0, nil } @@ -129,8 +136,8 @@ func (suite *TypesTestSuite) TestWasmInstantiate() { suite.Require().NoError(err) // Change the checksum to something else. - clientState := payload.ClientState - clientState.Checksum = []byte("new checksum") + wrappedClientState := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), payload.ClientState) + clientState := types.NewClientState(payload.ClientState, []byte("new checksum"), wrappedClientState.GetLatestHeight().(clienttypes.Height)) store.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), clientState)) resp, err := json.Marshal(types.UpdateStateResult{}) @@ -151,12 +158,13 @@ func (suite *TypesTestSuite) TestWasmInstantiate() { tc.malleate() initMsg := types.InstantiateMessage{ - ClientState: &types.ClientState{}, - ConsensusState: &types.ConsensusState{}, + ClientState: clienttypes.MustMarshalClientState(suite.chainA.App.AppCodec(), wasmtesting.MockTendermitClientState), + ConsensusState: clienttypes.MustMarshalConsensusState(suite.chainA.App.AppCodec(), wasmtesting.MockTendermintClientConsensusState), + Checksum: suite.checksum, } clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), defaultWasmClientID) - err := types.WasmInstantiate(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, &types.ClientState{}, initMsg) + err := types.WasmInstantiate(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, &types.ClientState{Checksum: suite.checksum}, initMsg) expPass := tc.expError == nil if expPass {