diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index 9ed3dd5a22f..0f3a291ffdf 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -170,7 +170,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { { "connection not found", func() { - channel.ConnectionHops = []string{"invalid-connnection-id"} + channel.ConnectionHops = []string{"invalid-connection-id"} path.EndpointA.SetChannel(*channel) }, connectiontypes.ErrConnectionNotFound, @@ -186,7 +186,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { { "invalid controller connection ID", func() { - metadata.ControllerConnectionId = "invalid-connnection-id" + metadata.ControllerConnectionId = "invalid-connection-id" versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) @@ -199,7 +199,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { { "invalid host connection ID", func() { - metadata.HostConnectionId = "invalid-connnection-id" + metadata.HostConnectionId = "invalid-connection-id" versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index 7c119b248ee..f69752acbae 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -188,7 +188,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { { "connection not found", func() { - channel.ConnectionHops = []string{"invalid-connnection-id"} + channel.ConnectionHops = []string{"invalid-connection-id"} path.EndpointB.SetChannel(*channel) }, connectiontypes.ErrConnectionNotFound, @@ -220,7 +220,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { { "invalid controller connection ID", func() { - metadata.ControllerConnectionId = "invalid-connnection-id" + metadata.ControllerConnectionId = "invalid-connection-id" versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) diff --git a/modules/core/03-connection/types/codec_test.go b/modules/core/03-connection/types/codec_test.go index ed9db95fb65..e70b72cd65b 100644 --- a/modules/core/03-connection/types/codec_test.go +++ b/modules/core/03-connection/types/codec_test.go @@ -1,6 +1,7 @@ package types_test import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -15,39 +16,39 @@ import ( func TestCodecTypeRegistration(t *testing.T) { testCases := []struct { - name string - typeURL string - expPass bool + name string + typeURL string + expError error }{ { "success: MsgConnectionOpenInit", sdk.MsgTypeURL(&types.MsgConnectionOpenInit{}), - true, + nil, }, { "success: MsgConnectionOpenTry", sdk.MsgTypeURL(&types.MsgConnectionOpenTry{}), - true, + nil, }, { "success: MsgConnectionOpenAck", sdk.MsgTypeURL(&types.MsgConnectionOpenAck{}), - true, + nil, }, { "success: MsgConnectionOpenConfirm", sdk.MsgTypeURL(&types.MsgConnectionOpenConfirm{}), - true, + nil, }, { "success: MsgUpdateParams", sdk.MsgTypeURL(&types.MsgUpdateParams{}), - true, + nil, }, { "type not registered on codec", "ibc.invalid.MsgTypeURL", - false, + fmt.Errorf("unable to resolve type URL ibc.invalid.MsgTypeURL"), }, } @@ -58,12 +59,12 @@ func TestCodecTypeRegistration(t *testing.T) { encodingCfg := moduletestutil.MakeTestEncodingConfig(testutil.CodecOptions{}, ibc.AppModule{}) msg, err := encodingCfg.Codec.InterfaceRegistry().Resolve(tc.typeURL) - if tc.expPass { + if tc.expError == nil { require.NotNil(t, msg) require.NoError(t, err) } else { require.Nil(t, msg) - require.Error(t, err) + require.ErrorContains(t, err, tc.expError.Error()) } }) } diff --git a/modules/core/03-connection/types/keys_test.go b/modules/core/03-connection/types/keys_test.go index bd929d63a42..816687077e9 100644 --- a/modules/core/03-connection/types/keys_test.go +++ b/modules/core/03-connection/types/keys_test.go @@ -1,12 +1,14 @@ package types_test import ( + "errors" "math" "testing" "github.com/stretchr/testify/require" "github.com/cosmos/ibc-go/v9/modules/core/03-connection/types" + host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ) // tests ParseConnectionSequence and IsValidConnectionID @@ -15,21 +17,21 @@ func TestParseConnectionSequence(t *testing.T) { name string connectionID string expSeq uint64 - expPass bool + expError error }{ - {"valid 0", "connection-0", 0, true}, - {"valid 1", "connection-1", 1, true}, - {"valid large sequence", types.FormatConnectionIdentifier(math.MaxUint64), math.MaxUint64, true}, + {"valid 0", "connection-0", 0, nil}, + {"valid 1", "connection-1", 1, nil}, + {"valid large sequence", types.FormatConnectionIdentifier(math.MaxUint64), math.MaxUint64, nil}, // one above uint64 max - {"invalid uint64", "connection-18446744073709551616", 0, false}, + {"invalid uint64", "connection-18446744073709551616", 0, errors.New("invalid connection identifier: failed to parse identifier sequence")}, // uint64 == 20 characters - {"invalid large sequence", "connection-2345682193567182931243", 0, false}, - {"capital prefix", "Connection-0", 0, false}, - {"double prefix", "connection-connection-0", 0, false}, - {"missing dash", "connection0", 0, false}, - {"blank id", " ", 0, false}, - {"empty id", "", 0, false}, - {"negative sequence", "connection--1", 0, false}, + {"invalid large sequence", "connection-2345682193567182931243", 0, host.ErrInvalidID}, + {"capital prefix", "Connection-0", 0, host.ErrInvalidID}, + {"double prefix", "connection-connection-0", 0, host.ErrInvalidID}, + {"missing dash", "connection0", 0, host.ErrInvalidID}, + {"blank id", " ", 0, host.ErrInvalidID}, + {"empty id", "", 0, host.ErrInvalidID}, + {"negative sequence", "connection--1", 0, host.ErrInvalidID}, } for _, tc := range testCases { @@ -40,11 +42,11 @@ func TestParseConnectionSequence(t *testing.T) { valid := types.IsValidConnectionID(tc.connectionID) require.Equal(t, tc.expSeq, seq) - if tc.expPass { + if tc.expError == nil { require.NoError(t, err, tc.name) require.True(t, valid) } else { - require.Error(t, err, tc.name) + require.ErrorContains(t, err, tc.expError.Error()) require.False(t, valid) } }) diff --git a/modules/core/03-connection/types/version_test.go b/modules/core/03-connection/types/version_test.go index e718801354c..bc377d6267e 100644 --- a/modules/core/03-connection/types/version_test.go +++ b/modules/core/03-connection/types/version_test.go @@ -11,14 +11,14 @@ import ( func TestValidateVersion(t *testing.T) { testCases := []struct { - name string - version *types.Version - expPass bool + name string + version *types.Version + expError error }{ - {"valid version", types.DefaultIBCVersion, true}, - {"valid empty feature set", types.NewVersion(types.DefaultIBCVersionIdentifier, []string{}), true}, - {"empty version identifier", types.NewVersion(" ", []string{"ORDER_UNORDERED"}), false}, - {"empty feature", types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_UNORDERED", " "}), false}, + {"valid version", types.DefaultIBCVersion, nil}, + {"valid empty feature set", types.NewVersion(types.DefaultIBCVersionIdentifier, []string{}), nil}, + {"empty version identifier", types.NewVersion(" ", []string{"ORDER_UNORDERED"}), types.ErrInvalidVersion}, + {"empty feature", types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_UNORDERED", " "}), types.ErrInvalidVersion}, } for i, tc := range testCases { @@ -26,10 +26,10 @@ func TestValidateVersion(t *testing.T) { err := types.ValidateVersion(tc.version) - if tc.expPass { + if tc.expError == nil { require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) } else { - require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + require.ErrorIs(t, err, tc.expError) } } } @@ -100,14 +100,14 @@ func TestPickVersion(t *testing.T) { supportedVersions []*types.Version counterpartyVersions []*types.Version expVer *types.Version - expPass bool + expError error }{ - {"valid default ibc version", types.GetCompatibleVersions(), types.GetCompatibleVersions(), types.DefaultIBCVersion, true}, - {"valid version in counterparty versions", types.GetCompatibleVersions(), []*types.Version{types.NewVersion("version1", nil), types.NewVersion("2.0.0", []string{"ORDER_UNORDERED-ZK"}), types.DefaultIBCVersion}, types.DefaultIBCVersion, true}, - {"valid identifier match but empty feature set not allowed", types.GetCompatibleVersions(), []*types.Version{types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"DAG", "ORDERED-ZK", "UNORDERED-zk]"})}, types.NewVersion(types.DefaultIBCVersionIdentifier, nil), false}, - {"empty counterparty versions", types.GetCompatibleVersions(), []*types.Version{}, &types.Version{}, false}, - {"non-matching counterparty versions", types.GetCompatibleVersions(), []*types.Version{types.NewVersion("2.0.0", nil)}, &types.Version{}, false}, - {"non-matching counterparty versions (uses ordered channels only) contained in supported versions (uses unordered channels only)", []*types.Version{types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_UNORDERED"})}, []*types.Version{types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_ORDERED"})}, &types.Version{}, false}, + {"valid default ibc version", types.GetCompatibleVersions(), types.GetCompatibleVersions(), types.DefaultIBCVersion, nil}, + {"valid version in counterparty versions", types.GetCompatibleVersions(), []*types.Version{types.NewVersion("version1", nil), types.NewVersion("2.0.0", []string{"ORDER_UNORDERED-ZK"}), types.DefaultIBCVersion}, types.DefaultIBCVersion, nil}, + {"valid identifier match but empty feature set not allowed", types.GetCompatibleVersions(), []*types.Version{types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"DAG", "ORDERED-ZK", "UNORDERED-zk]"})}, types.NewVersion(types.DefaultIBCVersionIdentifier, nil), types.ErrVersionNegotiationFailed}, + {"empty counterparty versions", types.GetCompatibleVersions(), []*types.Version{}, &types.Version{}, types.ErrVersionNegotiationFailed}, + {"non-matching counterparty versions", types.GetCompatibleVersions(), []*types.Version{types.NewVersion("2.0.0", nil)}, &types.Version{}, types.ErrVersionNegotiationFailed}, + {"non-matching counterparty versions (uses ordered channels only) contained in supported versions (uses unordered channels only)", []*types.Version{types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_UNORDERED"})}, []*types.Version{types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_ORDERED"})}, &types.Version{}, types.ErrVersionNegotiationFailed}, } for i, tc := range testCases { @@ -115,10 +115,10 @@ func TestPickVersion(t *testing.T) { version, err := types.PickVersion(tc.supportedVersions, tc.counterpartyVersions) - if tc.expPass { + if tc.expError == nil { require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) } else { - require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + require.ErrorIs(t, err, tc.expError) var emptyVersion *types.Version require.Equal(t, emptyVersion, version, "invalid test case %d passed: %s", i, tc.name) } @@ -130,13 +130,13 @@ func TestVerifyProposedVersion(t *testing.T) { name string proposedVersion *types.Version supportedVersion *types.Version - expPass bool + expError error }{ - {"entire feature set supported", types.DefaultIBCVersion, types.NewVersion("1", []string{"ORDER_ORDERED", "ORDER_UNORDERED", "ORDER_DAG"}), true}, - {"empty feature sets not supported", types.NewVersion("1", []string{}), types.DefaultIBCVersion, false}, - {"one feature missing", types.DefaultIBCVersion, types.NewVersion("1", []string{"ORDER_UNORDERED", "ORDER_DAG"}), false}, - {"both features missing", types.DefaultIBCVersion, types.NewVersion("1", []string{"ORDER_DAG"}), false}, - {"identifiers do not match", types.NewVersion("2", []string{"ORDER_UNORDERED", "ORDER_ORDERED"}), types.DefaultIBCVersion, false}, + {"entire feature set supported", types.DefaultIBCVersion, types.NewVersion("1", []string{"ORDER_ORDERED", "ORDER_UNORDERED", "ORDER_DAG"}), nil}, + {"empty feature sets not supported", types.NewVersion("1", []string{}), types.DefaultIBCVersion, types.ErrVersionNegotiationFailed}, + {"one feature missing", types.DefaultIBCVersion, types.NewVersion("1", []string{"ORDER_UNORDERED", "ORDER_DAG"}), types.ErrVersionNegotiationFailed}, + {"both features missing", types.DefaultIBCVersion, types.NewVersion("1", []string{"ORDER_DAG"}), types.ErrVersionNegotiationFailed}, + {"identifiers do not match", types.NewVersion("2", []string{"ORDER_UNORDERED", "ORDER_ORDERED"}), types.DefaultIBCVersion, types.ErrVersionNegotiationFailed}, } for i, tc := range testCases { @@ -144,10 +144,10 @@ func TestVerifyProposedVersion(t *testing.T) { err := tc.supportedVersion.VerifyProposedVersion(tc.proposedVersion) - if tc.expPass { + if tc.expError == nil { require.NoError(t, err, "test case %d: %s", i, tc.name) } else { - require.Error(t, err, "test case %d: %s", i, tc.name) + require.ErrorIs(t, err, tc.expError) } } } diff --git a/modules/core/04-channel/types/codec_test.go b/modules/core/04-channel/types/codec_test.go index b32e8439e05..54666b7179f 100644 --- a/modules/core/04-channel/types/codec_test.go +++ b/modules/core/04-channel/types/codec_test.go @@ -1,6 +1,7 @@ package types_test import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -15,114 +16,114 @@ import ( func TestCodecTypeRegistration(t *testing.T) { testCases := []struct { - name string - typeURL string - expPass bool + name string + typeURL string + expError error }{ { "success: Packet", sdk.MsgTypeURL(&types.Packet{}), - true, + nil, }, { "success: MsgChannelOpenInit", sdk.MsgTypeURL(&types.MsgChannelOpenInit{}), - true, + nil, }, { "success: MsgChannelOpenTry", sdk.MsgTypeURL(&types.MsgChannelOpenTry{}), - true, + nil, }, { "success: MsgChannelOpenAck", sdk.MsgTypeURL(&types.MsgChannelOpenAck{}), - true, + nil, }, { "success: MsgChannelOpenConfirm", sdk.MsgTypeURL(&types.MsgChannelOpenConfirm{}), - true, + nil, }, { "success: MsgChannelCloseInit", sdk.MsgTypeURL(&types.MsgChannelCloseInit{}), - true, + nil, }, { "success: MsgChannelCloseConfirm", sdk.MsgTypeURL(&types.MsgChannelCloseConfirm{}), - true, + nil, }, { "success: MsgRecvPacket", sdk.MsgTypeURL(&types.MsgRecvPacket{}), - true, + nil, }, { "success: MsgAcknowledgement", sdk.MsgTypeURL(&types.MsgAcknowledgement{}), - true, + nil, }, { "success: MsgTimeout", sdk.MsgTypeURL(&types.MsgTimeout{}), - true, + nil, }, { "success: MsgTimeoutOnClose", sdk.MsgTypeURL(&types.MsgTimeoutOnClose{}), - true, + nil, }, { "success: MsgChannelUpgradeInit", sdk.MsgTypeURL(&types.MsgChannelUpgradeInit{}), - true, + nil, }, { "success: MsgChannelUpgradeTry", sdk.MsgTypeURL(&types.MsgChannelUpgradeTry{}), - true, + nil, }, { "success: MsgChannelUpgradeAck", sdk.MsgTypeURL(&types.MsgChannelUpgradeAck{}), - true, + nil, }, { "success: MsgChannelUpgradeConfirm", sdk.MsgTypeURL(&types.MsgChannelUpgradeConfirm{}), - true, + nil, }, { "success: MsgChannelUpgradeOpen", sdk.MsgTypeURL(&types.MsgChannelUpgradeOpen{}), - true, + nil, }, { "success: MsgChannelUpgradeTimeout", sdk.MsgTypeURL(&types.MsgChannelUpgradeTimeout{}), - true, + nil, }, { "success: MsgChannelUpgradeCancel", sdk.MsgTypeURL(&types.MsgChannelUpgradeCancel{}), - true, + nil, }, { "success: MsgPruneAcknowledgements", sdk.MsgTypeURL(&types.MsgPruneAcknowledgements{}), - true, + nil, }, { "success: MsgUpdateParams", sdk.MsgTypeURL(&types.MsgUpdateParams{}), - true, + nil, }, { "type not registered on codec", "ibc.invalid.MsgTypeURL", - false, + fmt.Errorf("unable to resolve type URL ibc.invalid.MsgTypeURL"), }, } @@ -133,12 +134,12 @@ func TestCodecTypeRegistration(t *testing.T) { encodingCfg := moduletestutil.MakeTestEncodingConfig(testutil.CodecOptions{}, ibc.AppModule{}) msg, err := encodingCfg.Codec.InterfaceRegistry().Resolve(tc.typeURL) - if tc.expPass { + if tc.expError == nil { require.NotNil(t, msg) require.NoError(t, err) } else { require.Nil(t, msg) - require.Error(t, err) + require.ErrorContains(t, err, tc.expError.Error()) } }) } diff --git a/modules/core/04-channel/types/query.go b/modules/core/04-channel/types/query.go index e4ab05cb907..1bff1497c39 100644 --- a/modules/core/04-channel/types/query.go +++ b/modules/core/04-channel/types/query.go @@ -30,7 +30,7 @@ func NewQueryChannelClientStateResponse(identifiedClientState clienttypes.Identi } } -// UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (qccsr QueryChannelClientStateResponse) UnpackInterfaces(unpacker gogoprotoany.AnyUnpacker) error { return qccsr.IdentifiedClientState.UnpackInterfaces(unpacker) } @@ -45,7 +45,7 @@ func NewQueryChannelConsensusStateResponse(clientID string, anyConsensusState *g } } -// UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (qccsr QueryChannelConsensusStateResponse) UnpackInterfaces(unpacker gogoprotoany.AnyUnpacker) error { return unpacker.UnpackAny(qccsr.ConsensusState, new(exported.ConsensusState)) } diff --git a/modules/light-clients/06-solomachine/codec_test.go b/modules/light-clients/06-solomachine/codec_test.go index e0784b0d754..1cf92555421 100644 --- a/modules/light-clients/06-solomachine/codec_test.go +++ b/modules/light-clients/06-solomachine/codec_test.go @@ -1,7 +1,7 @@ package solomachine_test import ( - "errors" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -15,9 +15,9 @@ import ( func TestCodecTypeRegistration(t *testing.T) { testCases := []struct { - name string - typeURL string - expErr error + name string + typeURL string + expError error }{ { "success: ClientState", @@ -42,7 +42,7 @@ func TestCodecTypeRegistration(t *testing.T) { { "type not registered on codec", "ibc.invalid.MsgTypeURL", - errors.New("unable to resolve type URL ibc.invalid.MsgTypeURL"), + fmt.Errorf("unable to resolve type URL ibc.invalid.MsgTypeURL"), }, } @@ -53,13 +53,12 @@ func TestCodecTypeRegistration(t *testing.T) { encodingCfg := moduletestutil.MakeTestEncodingConfig(testutil.CodecOptions{}, solomachine.AppModuleBasic{}) msg, err := encodingCfg.Codec.InterfaceRegistry().Resolve(tc.typeURL) - if tc.expErr == nil { + if tc.expError == nil { require.NotNil(t, msg) require.NoError(t, err) } else { require.Nil(t, msg) - require.Error(t, err) - require.Contains(t, err.Error(), tc.expErr.Error()) + require.ErrorContains(t, err, tc.expError.Error()) } }) } diff --git a/modules/light-clients/07-tendermint/codec_test.go b/modules/light-clients/07-tendermint/codec_test.go index 01868765488..87c01eba8d6 100644 --- a/modules/light-clients/07-tendermint/codec_test.go +++ b/modules/light-clients/07-tendermint/codec_test.go @@ -1,6 +1,7 @@ package tendermint_test import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -14,34 +15,34 @@ import ( func TestCodecTypeRegistration(t *testing.T) { testCases := []struct { - name string - typeURL string - expPass bool + name string + typeURL string + expError error }{ { "success: ClientState", sdk.MsgTypeURL(&tendermint.ClientState{}), - true, + nil, }, { "success: ConsensusState", sdk.MsgTypeURL(&tendermint.ConsensusState{}), - true, + nil, }, { "success: Header", sdk.MsgTypeURL(&tendermint.Header{}), - true, + nil, }, { "success: Misbehaviour", sdk.MsgTypeURL(&tendermint.Misbehaviour{}), - true, + nil, }, { "type not registered on codec", "ibc.invalid.MsgTypeURL", - false, + fmt.Errorf("unable to resolve type URL ibc.invalid.MsgTypeURL"), }, } @@ -52,12 +53,12 @@ func TestCodecTypeRegistration(t *testing.T) { encodingCfg := moduletestutil.MakeTestEncodingConfig(testutil.CodecOptions{}, tendermint.AppModule{}) msg, err := encodingCfg.Codec.InterfaceRegistry().Resolve(tc.typeURL) - if tc.expPass { + if tc.expError == nil { require.NotNil(t, msg) require.NoError(t, err) } else { require.Nil(t, msg) - require.Error(t, err) + require.ErrorContains(t, err, tc.expError.Error()) } }) } diff --git a/modules/light-clients/07-tendermint/header_test.go b/modules/light-clients/07-tendermint/header_test.go index 8525b4b0f89..19716c8a19a 100644 --- a/modules/light-clients/07-tendermint/header_test.go +++ b/modules/light-clients/07-tendermint/header_test.go @@ -1,6 +1,7 @@ package tendermint_test import ( + "errors" "time" clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" @@ -23,34 +24,37 @@ func (suite *TendermintTestSuite) TestHeaderValidateBasic() { testCases := []struct { name string malleate func() - expPass bool + expErr error }{ - {"valid header", func() {}, true}, + {"valid header", func() {}, nil}, {"header is nil", func() { header.Header = nil - }, false}, + }, errors.New("tendermint header cannot be nil")}, {"signed header is nil", func() { header.SignedHeader = nil - }, false}, + }, errors.New("tendermint signed header cannot be nil")}, {"SignedHeaderFromProto failed", func() { header.SignedHeader.Commit.Height = -1 - }, false}, + }, errors.New("header is not a tendermint header")}, {"signed header failed tendermint ValidateBasic", func() { header = suite.chainA.LatestCommittedHeader header.SignedHeader.Commit = nil - }, false}, + }, errors.New("header failed basic validation")}, {"trusted height is equal to header height", func() { var ok bool header.TrustedHeight, ok = header.GetHeight().(clienttypes.Height) suite.Require().True(ok) - }, false}, + }, errors.New("invalid header height")}, {"validator set nil", func() { header.ValidatorSet = nil - }, false}, + }, errors.New("invalid client header")}, + {"ValidatorSetFromProto failed", func() { + header.ValidatorSet.Validators[0].VotingPower = -1 + }, errors.New("validator set is not tendermint validator set")}, {"header validator hash does not equal hash of validator set", func() { // use chainB's randomly generated validator set header.ValidatorSet = suite.chainB.LatestCommittedHeader.ValidatorSet - }, false}, + }, errors.New("validator set does not match hash")}, } suite.Require().Equal(exported.Tendermint, suite.header.ClientType()) @@ -67,10 +71,11 @@ func (suite *TendermintTestSuite) TestHeaderValidateBasic() { err := header.ValidateBasic() - if tc.expPass { + if tc.expErr == nil { suite.Require().NoError(err) } else { suite.Require().Error(err) + suite.Require().ErrorContains(err, tc.expErr.Error()) } }) } diff --git a/modules/light-clients/07-tendermint/misbehaviour_handle_test.go b/modules/light-clients/07-tendermint/misbehaviour_handle_test.go index 9f81e0d9343..ce49cb1ab89 100644 --- a/modules/light-clients/07-tendermint/misbehaviour_handle_test.go +++ b/modules/light-clients/07-tendermint/misbehaviour_handle_test.go @@ -1,6 +1,7 @@ package tendermint_test import ( + "errors" "fmt" "strings" "time" @@ -35,7 +36,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { testCases := []struct { name string malleate func() - expPass bool + expErr error }{ { "valid fork misbehaviour", func() { @@ -56,7 +57,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid time misbehaviour", func() { @@ -71,7 +72,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid time misbehaviour, header 1 time strictly less than header 2 time", func() { @@ -86,7 +87,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Hour), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid misbehavior at height greater than last consensusState", func() { @@ -100,7 +101,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, true, + }, nil, }, { "valid misbehaviour with different trusted heights", func() { @@ -124,7 +125,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight2, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals2, suite.chainB.Signers), } }, - true, + nil, }, { "valid misbehaviour at a previous revision", func() { @@ -149,7 +150,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { err = path.EndpointB.UpgradeChain() suite.Require().NoError(err) }, - true, + nil, }, { "valid misbehaviour at a future revision", func() { @@ -169,7 +170,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header2: suite.chainB.CreateTMClientHeader(futureRevision, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid misbehaviour with trusted heights at a previous revision", func() { @@ -191,7 +192,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "consensus state's valset hash different from misbehaviour should still pass", func() { @@ -216,7 +217,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), } - }, true, + }, nil, }, { "invalid misbehaviour: misbehaviour from different chain", func() { @@ -236,7 +237,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("invalid light client misbehaviour"), }, { "misbehaviour trusted validators does not match validator hash in trusted consensus state", func() { @@ -253,7 +254,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), } - }, false, + }, errors.New("invalid validator set"), }, { "trusted consensus state does not exist", func() { @@ -267,12 +268,12 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight.Increment().(clienttypes.Height), suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("consensus state not found"), }, { "invalid tendermint misbehaviour", func() { misbehaviour = &solomachine.Misbehaviour{} - }, false, + }, errors.New("invalid client type"), }, { "trusting period expired", func() { @@ -294,7 +295,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("time since latest trusted state has passed the trusting period"), }, { "header 1 valset has too much change", func() { @@ -314,7 +315,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, { "header 2 valset has too much change", func() { @@ -334,7 +335,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, { "both header 1 and header 2 valsets have too much change", func() { @@ -354,7 +355,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, } @@ -375,10 +376,11 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { err = lightClientModule.VerifyClientMessage(suite.chainA.GetContext(), path.EndpointA.ClientID, misbehaviour) - if tc.expPass { + if tc.expErr == nil { suite.Require().NoError(err) } else { suite.Require().Error(err) + suite.Require().ErrorContains(err, tc.expErr.Error()) } }) } @@ -411,7 +413,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { testCases := []struct { name string malleate func() - expPass bool + expErr error }{ { "valid fork misbehaviour", func() { @@ -432,7 +434,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid time misbehaviour", func() { @@ -447,7 +449,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid time misbehaviour, header 1 time strictly less than header 2 time", func() { @@ -462,7 +464,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Hour), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } }, - true, + nil, }, { "valid misbehavior at height greater than last consensusState", func() { @@ -476,7 +478,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, true, + }, nil, }, { "valid misbehaviour with different trusted heights", func() { @@ -500,7 +502,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight2, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals2, suite.chainB.Signers), } }, - true, + nil, }, { "consensus state's valset hash different from misbehaviour should still pass", func() { @@ -525,7 +527,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), } - }, true, + }, nil, }, { "invalid misbehaviour: misbehaviour from different chain", func() { @@ -545,7 +547,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, { "misbehaviour trusted validators does not match validator hash in trusted consensus state", func() { @@ -562,7 +564,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), } - }, false, + }, errors.New("invalid validator set"), }, { "trusted consensus state does not exist", func() { @@ -576,12 +578,12 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight.Increment().(clienttypes.Height), suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("consensus state not found"), }, { "invalid tendermint misbehaviour", func() { misbehaviour = &solomachine.Misbehaviour{} - }, false, + }, errors.New("nvalid client type"), }, { "trusting period expired", func() { @@ -603,7 +605,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("time since latest trusted state has passed the trusting period"), }, { "header 1 valset has too much change", func() { @@ -623,7 +625,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, { "header 2 valset has too much change", func() { @@ -643,7 +645,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, { "both header 1 and header 2 valsets have too much change", func() { @@ -663,7 +665,7 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), } - }, false, + }, errors.New("validator set in header has too much change from trusted validator set"), }, } @@ -684,10 +686,11 @@ func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { err = lightClientModule.VerifyClientMessage(suite.chainA.GetContext(), path.EndpointA.ClientID, misbehaviour) - if tc.expPass { + if tc.expErr == nil { suite.Require().NoError(err) } else { suite.Require().Error(err) + suite.Require().ErrorContains(err, tc.expErr.Error()) } }) } diff --git a/modules/light-clients/07-tendermint/misbehaviour_test.go b/modules/light-clients/07-tendermint/misbehaviour_test.go index b946a6d5856..55fad6068f5 100644 --- a/modules/light-clients/07-tendermint/misbehaviour_test.go +++ b/modules/light-clients/07-tendermint/misbehaviour_test.go @@ -1,9 +1,12 @@ package tendermint_test import ( + "errors" "time" + errorsmod "cosmossdk.io/errors" cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1" + "github.com/cometbft/cometbft/crypto/tmhash" cmttypes "github.com/cometbft/cometbft/types" @@ -48,7 +51,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { name string misbehaviour *ibctm.Misbehaviour malleateMisbehaviour func(misbehaviour *ibctm.Misbehaviour) error - expPass bool + expErr error }{ { "valid fork misbehaviour, two headers at same height have different time", @@ -58,7 +61,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - true, + nil, }, { "valid time misbehaviour, both headers at different heights are at same time", @@ -68,19 +71,19 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - true, + nil, }, { "misbehaviour Header1 is nil", ibctm.NewMisbehaviour(clientID, nil, suite.header), func(m *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(ibctm.ErrInvalidHeader, "misbehaviour Header1 cannot be nil"), }, { "misbehaviour Header2 is nil", ibctm.NewMisbehaviour(clientID, suite.header, nil), func(m *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(ibctm.ErrInvalidHeader, "misbehaviour Header2 cannot be nil"), }, { "valid misbehaviour with different trusted headers", @@ -90,7 +93,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - true, + nil, }, { "trusted height is 0 in Header1", @@ -100,7 +103,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(ibctm.ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero revision height"), }, { "trusted height is 0 in Header2", @@ -110,7 +113,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(ibctm.ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero revision height"), }, { "trusted valset is nil in Header1", @@ -120,7 +123,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(ibctm.ErrInvalidValidatorSet, "trusted validator set in Header1 cannot be empty"), }, { "trusted valset is nil in Header2", @@ -130,7 +133,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(ibctm.ErrInvalidValidatorSet, "trusted validator set in Header2 cannot be empty"), }, { "invalid client ID ", @@ -140,7 +143,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: "GAIA", }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errors.New("identifier GAIA has invalid length"), }, { "chainIDs do not match", @@ -150,7 +153,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errorsmod.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers must have identical chainIDs"), }, { "header2 height is greater", @@ -160,7 +163,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { ClientId: clientID, }, func(misbehaviour *ibctm.Misbehaviour) error { return nil }, - false, + errors.New("Header1 height is less than Header2 height"), }, { "header 1 doesn't have 2/3 majority", @@ -181,7 +184,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { misbehaviour.Header1.Commit = extCommit.ToCommit().ToProto() return err }, - false, + errors.New("validator set did not commit to header"), }, { "header 2 doesn't have 2/3 majority", @@ -202,7 +205,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { misbehaviour.Header2.Commit = extCommit.ToCommit().ToProto() return err }, - false, + errors.New("validator set did not commit to header"), }, { "validators sign off on wrong commit", @@ -216,7 +219,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { misbehaviour.Header2.Commit.BlockID = tmBlockID.ToProto() return nil }, - false, + errors.New("header 2 failed validation"), }, } @@ -226,11 +229,13 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { suite.Run(tc.name, func() { err := tc.malleateMisbehaviour(tc.misbehaviour) suite.Require().NoError(err) + err = tc.misbehaviour.ValidateBasic() - if tc.expPass { - suite.Require().NoError(tc.misbehaviour.ValidateBasic(), "valid test case %d failed: %s", i, tc.name) + if tc.expErr == nil { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) } else { - suite.Require().Error(tc.misbehaviour.ValidateBasic(), "invalid test case %d passed: %s", i, tc.name) + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + suite.Require().ErrorContains(err, tc.expErr.Error()) } }) } diff --git a/modules/light-clients/07-tendermint/proposal_handle_test.go b/modules/light-clients/07-tendermint/proposal_handle_test.go index 703651ca265..e114dc3f50e 100644 --- a/modules/light-clients/07-tendermint/proposal_handle_test.go +++ b/modules/light-clients/07-tendermint/proposal_handle_test.go @@ -70,17 +70,17 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { testCases := []struct { name string FreezeClient bool - expPass bool + expError error }{ { name: "PASS: update checks are deprecated, client is not frozen", FreezeClient: false, - expPass: true, + expError: nil, }, { name: "PASS: update checks are deprecated, client is frozen", FreezeClient: true, - expPass: true, + expError: nil, }, } @@ -138,7 +138,7 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) - if tc.expPass { + if tc.expError == nil { suite.Require().NoError(err) updatedClient, ok := subjectPath.EndpointA.GetClientState().(*ibctm.ClientState) @@ -165,6 +165,7 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { suite.Require().Equal(time.Hour*24*7, updatedClient.TrustingPeriod) } else { suite.Require().Error(err) + suite.Require().ErrorContains(err, tc.expError.Error()) } }) } @@ -179,7 +180,7 @@ func (suite *TendermintTestSuite) TestIsMatchingClientState() { testCases := []struct { name string malleate func() - expPass bool + isMatch bool }{ { "matching clients", func() { @@ -235,7 +236,7 @@ func (suite *TendermintTestSuite) TestIsMatchingClientState() { tc.malleate() - suite.Require().Equal(tc.expPass, ibctm.IsMatchingClientState(*subjectClientState, *substituteClientState)) + suite.Require().Equal(tc.isMatch, ibctm.IsMatchingClientState(*subjectClientState, *substituteClientState)) }) } } diff --git a/modules/light-clients/07-tendermint/update_test.go b/modules/light-clients/07-tendermint/update_test.go index ab4deca0f86..d9d79e0d746 100644 --- a/modules/light-clients/07-tendermint/update_test.go +++ b/modules/light-clients/07-tendermint/update_test.go @@ -1,6 +1,7 @@ package tendermint_test import ( + "errors" "time" storetypes "cosmossdk.io/store/types" @@ -39,12 +40,12 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { testCases := []struct { name string malleate func() - expPass bool + expErr error }{ { name: "success", malleate: func() {}, - expPass: true, + expErr: nil, }, { name: "successful verify header for header with a previous height", @@ -64,7 +65,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { err = path.EndpointA.UpdateClient() suite.Require().NoError(err) }, - expPass: true, + expErr: nil, }, { name: "successful verify header: header with future height and different validator set", @@ -82,7 +83,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+5, trustedHeight, suite.chainB.ProposedHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners) }, - expPass: true, + expErr: nil, }, { name: "successful verify header: header with next height and different validator set", @@ -100,7 +101,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners) }, - expPass: true, + expErr: nil, }, { name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state", @@ -115,7 +116,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time, bothValSet, bothValSet, bothValSet, bothSigners) }, - expPass: false, + expErr: errors.New("invalid validator set"), }, { name: "unsuccessful verify header with next height: update header mismatches nextValSetHash", @@ -129,7 +130,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { // this will err as altValSet.Hash() != consState.NextValidatorsHash header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time, altValSet, altValSet, trustedVals, altSigners) }, - expPass: false, + expErr: errors.New("failed to verify header"), }, { name: "unsuccessful update with future height: too much change in validator set", @@ -142,7 +143,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time, altValSet, altValSet, trustedVals, altSigners) }, - expPass: false, + expErr: errors.New("failed to verify header: can't trust new val set"), }, { name: "unsuccessful verify header: header height revision and trusted height revision mismatch", @@ -154,7 +155,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(chainIDRevision1, 3, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) }, - expPass: false, + expErr: errors.New("invalid client header"), }, { name: "unsuccessful verify header: header height < consensus height", @@ -170,7 +171,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { // Make new header at height less than latest client state header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(heightMinus1.RevisionHeight), trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) }, - expPass: false, + expErr: errors.New("invalid client header"), }, { name: "unsuccessful verify header: header basic validation failed", @@ -178,7 +179,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { // cause header to fail validatebasic by changing commit height to mismatch header height header.SignedHeader.Commit.Height = revisionHeight - 1 }, - expPass: false, + expErr: errors.New("header and commit height mismatch"), }, { name: "unsuccessful verify header: header timestamp is not past last client timestamp", @@ -191,7 +192,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time.Add(-time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) }, - expPass: false, + expErr: errors.New("failed to verify header"), }, { name: "unsuccessful verify header: header with incorrect header chain-id", @@ -204,7 +205,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(chainID, suite.chainB.ProposedHeader.Height+1, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) }, - expPass: false, + expErr: errors.New("header height revision 0 does not match trusted header revision 1"), }, { name: "unsuccessful update: trusting period has passed since last client timestamp", @@ -219,7 +220,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { suite.chainB.ExpireClient(ibctesting.TrustingPeriod) }, - expPass: false, + expErr: errors.New("failed to verify header"), }, { name: "unsuccessful update for a previous revision", @@ -237,7 +238,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { err = path.EndpointB.UpgradeChain() suite.Require().NoError(err) }, - expPass: false, + expErr: errors.New("failed to verify header"), }, { name: "successful update with identical header to a previous update", @@ -255,7 +256,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { err = path.EndpointA.UpdateClient() suite.Require().NoError(err) }, - expPass: true, + expErr: nil, }, { @@ -269,7 +270,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID+"-1", suite.chainB.ProposedHeader.Height+5, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) }, - expPass: false, + expErr: errors.New("failed to verify header"), }, { @@ -287,7 +288,7 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.ProposedHeader.Height, trustedHeight, suite.chainB.ProposedHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) }, - expPass: false, + expErr: errors.New("header height revision 2 does not match trusted header revision 1"), }, } @@ -314,10 +315,11 @@ func (suite *TendermintTestSuite) TestVerifyHeader() { err = lightClientModule.VerifyClientMessage(suite.chainA.GetContext(), path.EndpointA.ClientID, header) - if tc.expPass { + if tc.expErr == nil { suite.Require().NoError(err, tc.name) } else { suite.Require().Error(err) + suite.Require().ErrorContains(err, tc.expErr.Error()) } }) } diff --git a/modules/light-clients/08-wasm/types/codec_test.go b/modules/light-clients/08-wasm/types/codec_test.go index e41411fd68b..1df1c2a3000 100644 --- a/modules/light-clients/08-wasm/types/codec_test.go +++ b/modules/light-clients/08-wasm/types/codec_test.go @@ -16,9 +16,9 @@ import ( func TestCodecTypeRegistration(t *testing.T) { testCases := []struct { - name string - typeURL string - expErr error + name string + typeURL string + expError error }{ { "success: ClientState", @@ -64,13 +64,12 @@ func TestCodecTypeRegistration(t *testing.T) { encodingCfg := moduletestutil.MakeTestEncodingConfig(testutil.CodecOptions{}, wasm.AppModule{}) msg, err := encodingCfg.Codec.InterfaceRegistry().Resolve(tc.typeURL) - if tc.expErr == nil { + if tc.expError == nil { require.NotNil(t, msg) require.NoError(t, err) } else { require.Nil(t, msg) - require.Error(t, err) - require.Equal(t, err.Error(), tc.expErr.Error()) + require.ErrorContains(t, err, tc.expError.Error()) } }) }