Remove Last Header from ClientState (#6873)
* implement features, fix tendermint tests * allow test headers to pass in custom nextvalidatorset * allow updates to previous heights and test * remove unnecessary testing feature * fix client tests * fix ibc tests, and updating consensus state * fix ibc-transfer tests * appease linter * Apply suggestions from code review Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add chainID test case * fix expPass value * Apply suggestions from code review Co-authored-by: colin axner <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * address rest of @colin-axner review * fix bug and errors * Apply suggestions from code review Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * address rest of @colin-axner review * implement updating before frozen height Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: colin axner <25233464+colin-axner@users.noreply.github.com>
This commit is contained in:
parent
0daf3c3271
commit
9b61e0947e
|
@ -136,7 +136,12 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
|
||||||
|
|
||||||
// commit genesis changes
|
// commit genesis changes
|
||||||
app.Commit()
|
app.Commit()
|
||||||
app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash}})
|
app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{
|
||||||
|
Height: app.LastBlockHeight() + 1,
|
||||||
|
AppHash: app.LastCommitID().Hash,
|
||||||
|
ValidatorsHash: valSet.Hash(),
|
||||||
|
NextValidatorsHash: valSet.Hash(),
|
||||||
|
}})
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ type ClientState interface {
|
||||||
ClientType() ClientType
|
ClientType() ClientType
|
||||||
GetLatestHeight() uint64
|
GetLatestHeight() uint64
|
||||||
IsFrozen() bool
|
IsFrozen() bool
|
||||||
|
GetFrozenHeight() uint64
|
||||||
Validate() error
|
Validate() error
|
||||||
GetProofSpecs() []*ics23.ProofSpec
|
GetProofSpecs() []*ics23.ProofSpec
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,8 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H
|
||||||
return nil, sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID)
|
return nil, sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addition to spec: prevent update if the client is frozen
|
// prevent update if the client is frozen before or at header height
|
||||||
if clientState.IsFrozen() {
|
if clientState.IsFrozen() && clientState.GetFrozenHeight() <= header.GetHeight() {
|
||||||
return nil, sdkerrors.Wrapf(types.ErrClientFrozen, "cannot update client with ID %s", clientID)
|
return nil, sdkerrors.Wrapf(types.ErrClientFrozen, "cannot update client with ID %s", clientID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +71,16 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H
|
||||||
|
|
||||||
switch clientType {
|
switch clientType {
|
||||||
case exported.Tendermint:
|
case exported.Tendermint:
|
||||||
|
trustedConsState, found := k.GetClientConsensusStateLTE(ctx, clientID, header.GetHeight())
|
||||||
|
if !found {
|
||||||
|
return nil, sdkerrors.Wrapf(types.ErrConsensusStateNotFound, "could not find consensus state less than header height: %d to verify header against", header.GetHeight())
|
||||||
|
}
|
||||||
clientState, consensusState, err = tendermint.CheckValidityAndUpdateState(
|
clientState, consensusState, err = tendermint.CheckValidityAndUpdateState(
|
||||||
clientState, header, ctx.BlockTime(),
|
clientState, trustedConsState, header, ctx.BlockTime(),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
err = sdkerrors.Wrapf(err, "failed to update client using trusted consensus state height %d", trustedConsState.GetHeight())
|
||||||
|
}
|
||||||
case exported.Localhost:
|
case exported.Localhost:
|
||||||
// override client state and update the block height
|
// override client state and update the block height
|
||||||
clientState = localhosttypes.NewClientState(
|
clientState = localhosttypes.NewClientState(
|
||||||
|
|
|
@ -38,12 +38,12 @@ func (suite *KeeperTestSuite) TestCreateClient() {
|
||||||
i := i
|
i := i
|
||||||
if tc.expPanic {
|
if tc.expPanic {
|
||||||
suite.Require().Panics(func() {
|
suite.Require().Panics(func() {
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err := ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
suite.Require().NoError(err, "err on client state initialization")
|
suite.Require().NoError(err, "err on client state initialization")
|
||||||
suite.keeper.CreateClient(suite.ctx, tc.clientID, clientState, suite.consensusState)
|
suite.keeper.CreateClient(suite.ctx, tc.clientID, clientState, suite.consensusState)
|
||||||
}, "Msg %d didn't panic: %s", i, tc.msg)
|
}, "Msg %d didn't panic: %s", i, tc.msg)
|
||||||
} else {
|
} else {
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err := ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
if tc.expPass {
|
if tc.expPass {
|
||||||
suite.Require().NoError(err, "errored on initialization")
|
suite.Require().NoError(err, "errored on initialization")
|
||||||
suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg)
|
suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg)
|
||||||
|
@ -64,15 +64,19 @@ func (suite *KeeperTestSuite) TestCreateClient() {
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
||||||
// Must create header creation functions since suite.header gets recreated on each test case
|
// Must create header creation functions since suite.header gets recreated on each test case
|
||||||
createValidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
|
createFutureUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
|
||||||
return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height+1, suite.header.Time.Add(time.Minute),
|
return ibctmtypes.CreateTestHeader(testChainID, suite.header.Height+1, suite.header.Time.Add(time.Minute),
|
||||||
suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
||||||
}
|
}
|
||||||
createInvalidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
|
createPastUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
|
||||||
return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height-3, suite.header.Time.Add(time.Minute),
|
return ibctmtypes.CreateTestHeader(testChainID, suite.header.Height-3, suite.header.Time,
|
||||||
suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
||||||
}
|
}
|
||||||
var updateHeader ibctmtypes.Header
|
var (
|
||||||
|
updateHeader ibctmtypes.Header
|
||||||
|
clientState ibctmtypes.ClientState
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -80,41 +84,95 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
||||||
expPass bool
|
expPass bool
|
||||||
}{
|
}{
|
||||||
{"valid update", func() error {
|
{"valid update", func() error {
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err = ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
_, err = suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||||
updateHeader = createValidUpdateFn(suite)
|
updateHeader = createFutureUpdateFn(suite)
|
||||||
return err
|
return err
|
||||||
}, true},
|
}, true},
|
||||||
|
{"valid past update", func() error {
|
||||||
|
clientState, err = ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||||
|
|
||||||
|
// store previous consensus state
|
||||||
|
prevConsState := ibctmtypes.ConsensusState{
|
||||||
|
Height: 1,
|
||||||
|
Timestamp: suite.past,
|
||||||
|
NextValidatorsHash: suite.valSet.Hash(),
|
||||||
|
ValidatorSet: suite.valSet,
|
||||||
|
}
|
||||||
|
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, 1, prevConsState)
|
||||||
|
|
||||||
|
// updateHeader will fill in consensus state between prevConsState and suite.consState
|
||||||
|
// clientState should not be updated
|
||||||
|
updateHeader = createPastUpdateFn(suite)
|
||||||
|
return nil
|
||||||
|
}, true},
|
||||||
{"client type not found", func() error {
|
{"client type not found", func() error {
|
||||||
updateHeader = createValidUpdateFn(suite)
|
updateHeader = createFutureUpdateFn(suite)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, false},
|
}, false},
|
||||||
{"client type and header type mismatch", func() error {
|
{"client type and header type mismatch", func() error {
|
||||||
suite.keeper.SetClientType(suite.ctx, testClientID, invalidClientType)
|
suite.keeper.SetClientType(suite.ctx, testClientID, invalidClientType)
|
||||||
updateHeader = createValidUpdateFn(suite)
|
updateHeader = createFutureUpdateFn(suite)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, false},
|
}, false},
|
||||||
{"client state not found", func() error {
|
{"client state not found", func() error {
|
||||||
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
|
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
|
||||||
updateHeader = createValidUpdateFn(suite)
|
updateHeader = createFutureUpdateFn(suite)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, false},
|
}, false},
|
||||||
{"frozen client", func() error {
|
{"consensus state not found", func() error {
|
||||||
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LastHeader: suite.header}
|
clientState, err = ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
|
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
|
||||||
updateHeader = createValidUpdateFn(suite)
|
updateHeader = createFutureUpdateFn(suite)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, false},
|
}, false},
|
||||||
|
{"frozen client before update", func() error {
|
||||||
|
clientState = ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
|
||||||
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
|
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
|
||||||
|
updateHeader = createFutureUpdateFn(suite)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}, false},
|
||||||
|
{"valid past update before client was frozen", func() error {
|
||||||
|
clientState, err = ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
clientState.FrozenHeight = testClientHeight - 1
|
||||||
|
_, err = suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||||
|
|
||||||
|
// store previous consensus state
|
||||||
|
prevConsState := ibctmtypes.ConsensusState{
|
||||||
|
Height: 1,
|
||||||
|
Timestamp: suite.past,
|
||||||
|
NextValidatorsHash: suite.valSet.Hash(),
|
||||||
|
ValidatorSet: suite.valSet,
|
||||||
|
}
|
||||||
|
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, 1, prevConsState)
|
||||||
|
|
||||||
|
// updateHeader will fill in consensus state between prevConsState and suite.consState
|
||||||
|
// clientState should not be updated
|
||||||
|
updateHeader = createPastUpdateFn(suite)
|
||||||
|
return nil
|
||||||
|
}, true},
|
||||||
{"invalid header", func() error {
|
{"invalid header", func() error {
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err = ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -122,7 +180,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
updateHeader = createInvalidUpdateFn(suite)
|
updateHeader = createPastUpdateFn(suite)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, false},
|
}, false},
|
||||||
|
@ -145,13 +203,14 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
||||||
suite.Require().NoError(err, err)
|
suite.Require().NoError(err, err)
|
||||||
|
|
||||||
expConsensusState := ibctmtypes.ConsensusState{
|
expConsensusState := ibctmtypes.ConsensusState{
|
||||||
Height: updateHeader.GetHeight(),
|
Height: updateHeader.GetHeight(),
|
||||||
Timestamp: updateHeader.Time,
|
Timestamp: updateHeader.Time,
|
||||||
Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash),
|
||||||
ValidatorSet: updateHeader.ValidatorSet,
|
NextValidatorsHash: updateHeader.NextValidatorsHash,
|
||||||
|
ValidatorSet: updateHeader.ValidatorSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
|
newClientState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
|
||||||
suite.Require().True(found, "valid test case %d failed: %s", i, tc.name)
|
suite.Require().True(found, "valid test case %d failed: %s", i, tc.name)
|
||||||
|
|
||||||
consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, updateHeader.GetHeight())
|
consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, updateHeader.GetHeight())
|
||||||
|
@ -161,16 +220,20 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
||||||
// recalculate cached totalVotingPower field for equality check
|
// recalculate cached totalVotingPower field for equality check
|
||||||
tmConsState.ValidatorSet.TotalVotingPower()
|
tmConsState.ValidatorSet.TotalVotingPower()
|
||||||
|
|
||||||
tmClientState, ok := updatedClientState.(ibctmtypes.ClientState)
|
// check returned client state is same as client state in store
|
||||||
suite.Require().True(ok, "client state is not a tendermint client state")
|
suite.Require().Equal(updatedClientState, newClientState, "updatedClient state not persisted correctly")
|
||||||
|
|
||||||
// recalculate cached totalVotingPower field for equality check
|
// Determine if clientState should be updated or not
|
||||||
tmClientState.LastHeader.ValidatorSet.TotalVotingPower()
|
if uint64(updateHeader.Height) > clientState.GetLatestHeight() {
|
||||||
|
// Header Height is greater than clientState latest Height, clientState should be updated with header.Height
|
||||||
|
suite.Require().Equal(uint64(updateHeader.Height), updatedClientState.GetLatestHeight(), "clientstate height did not update")
|
||||||
|
} else {
|
||||||
|
// Update will add past consensus state, clientState should not be updated at all
|
||||||
|
suite.Require().Equal(clientState.GetLatestHeight(), updatedClientState.GetLatestHeight(), "client state height updated for past header")
|
||||||
|
}
|
||||||
|
|
||||||
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name)
|
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name)
|
||||||
suite.Require().Equal(updateHeader.GetHeight(), clientState.GetLatestHeight(), "client state height not updated correctly on case %s", tc.name)
|
|
||||||
suite.Require().Equal(expConsensusState, consensusState, "consensus state should have been updated on case %s", tc.name)
|
suite.Require().Equal(expConsensusState, consensusState, "consensus state should have been updated on case %s", tc.name)
|
||||||
suite.Require().Equal(updatedClientState, tmClientState, "client states don't match")
|
|
||||||
} else {
|
} else {
|
||||||
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name)
|
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name)
|
||||||
}
|
}
|
||||||
|
@ -228,7 +291,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
||||||
},
|
},
|
||||||
func() error {
|
func() error {
|
||||||
suite.consensusState.ValidatorSet = bothValSet
|
suite.consensusState.ValidatorSet = bothValSet
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err := ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -248,7 +311,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
||||||
},
|
},
|
||||||
func() error {
|
func() error {
|
||||||
suite.consensusState.ValidatorSet = bothValSet
|
suite.consensusState.ValidatorSet = bothValSet
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err := ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -273,7 +336,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
||||||
ClientID: testClientID,
|
ClientID: testClientID,
|
||||||
},
|
},
|
||||||
func() error {
|
func() error {
|
||||||
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LastHeader: suite.header}
|
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
|
||||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -288,7 +351,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
||||||
ClientID: testClientID,
|
ClientID: testClientID,
|
||||||
},
|
},
|
||||||
func() error {
|
func() error {
|
||||||
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LastHeader: suite.header}
|
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
|
||||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -303,7 +366,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
||||||
ClientID: testClientID,
|
ClientID: testClientID,
|
||||||
},
|
},
|
||||||
func() error {
|
func() error {
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err := ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,10 +211,11 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported.
|
||||||
valSet := stakingtypes.Validators(histInfo.Valset)
|
valSet := stakingtypes.Validators(histInfo.Valset)
|
||||||
|
|
||||||
consensusState := ibctmtypes.ConsensusState{
|
consensusState := ibctmtypes.ConsensusState{
|
||||||
Height: height,
|
Height: height,
|
||||||
Timestamp: histInfo.Header.Time,
|
Timestamp: histInfo.Header.Time,
|
||||||
Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash),
|
||||||
ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()),
|
NextValidatorsHash: histInfo.Header.NextValidatorsHash,
|
||||||
|
ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()),
|
||||||
}
|
}
|
||||||
return consensusState, true
|
return consensusState, true
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
testChainID = "gaiahub"
|
||||||
|
|
||||||
testClientID = "gaiachain"
|
testClientID = "gaiachain"
|
||||||
testClientID2 = "ethbridge"
|
testClientID2 = "ethbridge"
|
||||||
testClientID3 = "ethermint"
|
testClientID3 = "ethermint"
|
||||||
|
@ -45,11 +47,13 @@ type KeeperTestSuite struct {
|
||||||
valSet *tmtypes.ValidatorSet
|
valSet *tmtypes.ValidatorSet
|
||||||
privVal tmtypes.PrivValidator
|
privVal tmtypes.PrivValidator
|
||||||
now time.Time
|
now time.Time
|
||||||
|
past time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) SetupTest() {
|
func (suite *KeeperTestSuite) SetupTest() {
|
||||||
isCheckTx := false
|
isCheckTx := false
|
||||||
suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
|
suite.now = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
|
||||||
|
suite.past = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
now2 := suite.now.Add(time.Hour)
|
now2 := suite.now.Add(time.Hour)
|
||||||
app := simapp.Setup(isCheckTx)
|
app := simapp.Setup(isCheckTx)
|
||||||
|
|
||||||
|
@ -63,12 +67,13 @@ func (suite *KeeperTestSuite) SetupTest() {
|
||||||
|
|
||||||
validator := tmtypes.NewValidator(pubKey, 1)
|
validator := tmtypes.NewValidator(pubKey, 1)
|
||||||
suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
|
suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
|
||||||
suite.header = ibctmtypes.CreateTestHeader(testClientID, testClientHeight, now2, suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
suite.header = ibctmtypes.CreateTestHeader(testChainID, testClientHeight, now2, suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
||||||
suite.consensusState = ibctmtypes.ConsensusState{
|
suite.consensusState = ibctmtypes.ConsensusState{
|
||||||
Height: testClientHeight,
|
Height: testClientHeight,
|
||||||
Timestamp: suite.now,
|
Timestamp: suite.now,
|
||||||
Root: commitmenttypes.NewMerkleRoot([]byte("hash")),
|
Root: commitmenttypes.NewMerkleRoot([]byte("hash")),
|
||||||
ValidatorSet: suite.valSet,
|
NextValidatorsHash: suite.valSet.Hash(),
|
||||||
|
ValidatorSet: suite.valSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
var validators stakingtypes.Validators
|
var validators stakingtypes.Validators
|
||||||
|
@ -90,7 +95,7 @@ func TestKeeperTestSuite(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) TestSetClientState() {
|
func (suite *KeeperTestSuite) TestSetClientState() {
|
||||||
clientState := ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs())
|
clientState := ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs())
|
||||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
|
|
||||||
retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
|
retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
|
||||||
|
@ -124,9 +129,9 @@ func (suite KeeperTestSuite) TestGetAllClients() {
|
||||||
testClientID2, testClientID3, testClientID,
|
testClientID2, testClientID3, testClientID,
|
||||||
}
|
}
|
||||||
expClients := []exported.ClientState{
|
expClients := []exported.ClientState{
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range expClients {
|
for i := range expClients {
|
||||||
|
@ -148,9 +153,9 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() {
|
||||||
testClientID2, testClientID3, testClientID,
|
testClientID2, testClientID3, testClientID,
|
||||||
}
|
}
|
||||||
expClients := []exported.ClientState{
|
expClients := []exported.ClientState{
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
}
|
}
|
||||||
|
|
||||||
expGenClients := make([]types.GenesisClientState, len(expClients))
|
expGenClients := make([]types.GenesisClientState, len(expClients))
|
||||||
|
@ -198,7 +203,7 @@ func (suite KeeperTestSuite) TestGetConsensusState() {
|
||||||
|
|
||||||
func (suite KeeperTestSuite) TestConsensusStateHelpers() {
|
func (suite KeeperTestSuite) TestConsensusStateHelpers() {
|
||||||
// initial setup
|
// initial setup
|
||||||
clientState, err := ibctmtypes.Initialize(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState, err := ibctmtypes.Initialize(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs())
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
|
@ -214,7 +219,7 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() {
|
||||||
header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.header.Time.Add(time.Minute), suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, suite.header.Time.Add(time.Minute), suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
||||||
|
|
||||||
// mock update functionality
|
// mock update functionality
|
||||||
clientState.LastHeader = header
|
clientState.LatestHeight = uint64(header.Height)
|
||||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+5, nextState)
|
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+5, nextState)
|
||||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||||
|
|
||||||
|
@ -238,10 +243,10 @@ func (suite KeeperTestSuite) TestGetAllConsensusStates() {
|
||||||
testClientID,
|
testClientID,
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.consensusState.GetHeight(), &tmtypes.ValidatorSet{},
|
suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.consensusState.GetHeight(), nil, &tmtypes.ValidatorSet{},
|
||||||
),
|
),
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
suite.consensusState.Timestamp.Add(time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash")), suite.consensusState.GetHeight()+1, &tmtypes.ValidatorSet{},
|
suite.consensusState.Timestamp.Add(time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash")), suite.consensusState.GetHeight()+1, nil, &tmtypes.ValidatorSet{},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -249,7 +254,7 @@ func (suite KeeperTestSuite) TestGetAllConsensusStates() {
|
||||||
testClientID2,
|
testClientID2,
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
suite.consensusState.Timestamp.Add(2*time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash_2")), suite.consensusState.GetHeight()+2, &tmtypes.ValidatorSet{},
|
suite.consensusState.Timestamp.Add(2*time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash_2")), suite.consensusState.GetHeight()+2, nil, &tmtypes.ValidatorSet{},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -17,8 +17,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
chainID = "chainID"
|
||||||
clientID = "ethbridge"
|
clientID = "ethbridge"
|
||||||
|
|
||||||
|
height = 10
|
||||||
|
|
||||||
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2
|
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2
|
||||||
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3
|
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3
|
||||||
maxClockDrift time.Duration = time.Second * 10
|
maxClockDrift time.Duration = time.Second * 10
|
||||||
|
@ -34,7 +37,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
val := tmtypes.NewValidator(pubKey, 10)
|
val := tmtypes.NewValidator(pubKey, 10)
|
||||||
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
|
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
|
||||||
|
|
||||||
header := ibctmtypes.CreateTestHeader("chainID", 10, now, valSet, []tmtypes.PrivValidator{privVal})
|
header := ibctmtypes.CreateTestHeader(chainID, height, now, valSet, []tmtypes.PrivValidator{privVal})
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -51,7 +54,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genState: types.NewGenesisState(
|
genState: types.NewGenesisState(
|
||||||
[]types.GenesisClientState{
|
[]types.GenesisClientState{
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
clientID, ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, commitmenttypes.GetSDKSpecs()),
|
clientID, ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10),
|
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10),
|
||||||
|
@ -62,7 +65,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
clientID,
|
clientID,
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), header.GetHeight(), header.ValidatorSet,
|
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), header.GetHeight(), header.ValidatorSet.Hash(), header.ValidatorSet,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -76,7 +79,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genState: types.NewGenesisState(
|
genState: types.NewGenesisState(
|
||||||
[]types.GenesisClientState{
|
[]types.GenesisClientState{
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
"/~@$*", ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, commitmenttypes.GetSDKSpecs()),
|
"/~@$*", ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10),
|
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10),
|
||||||
|
@ -87,7 +90,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
clientID,
|
clientID,
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), header.GetHeight(), header.ValidatorSet,
|
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), header.GetHeight(), header.ValidatorSet.Hash(), header.ValidatorSet,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -102,7 +105,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genState: types.NewGenesisState(
|
genState: types.NewGenesisState(
|
||||||
[]types.GenesisClientState{
|
[]types.GenesisClientState{
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
clientID, ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, commitmenttypes.GetSDKSpecs()),
|
clientID, ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
types.NewGenesisClientState(exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 0)),
|
types.NewGenesisClientState(exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 0)),
|
||||||
},
|
},
|
||||||
|
@ -116,7 +119,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genState: types.NewGenesisState(
|
genState: types.NewGenesisState(
|
||||||
[]types.GenesisClientState{
|
[]types.GenesisClientState{
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
clientID, ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, commitmenttypes.GetSDKSpecs()),
|
clientID, ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
|
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
|
||||||
|
@ -127,7 +130,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
"CLIENTID2",
|
"CLIENTID2",
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.ValidatorSet,
|
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.ValidatorSet.Hash(), header.ValidatorSet,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -141,7 +144,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genState: types.NewGenesisState(
|
genState: types.NewGenesisState(
|
||||||
[]types.GenesisClientState{
|
[]types.GenesisClientState{
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
clientID, ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, commitmenttypes.GetSDKSpecs()),
|
clientID, ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
types.NewGenesisClientState(
|
types.NewGenesisClientState(
|
||||||
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
|
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
|
||||||
|
@ -152,7 +155,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
clientID,
|
clientID,
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.ValidatorSet,
|
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.ValidatorSet.Hash(), header.ValidatorSet,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"valid misbehavior evidence",
|
"valid misbehavior evidence",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -69,7 +69,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"valid misbehavior at height greater than last consensusState",
|
"valid misbehavior at height greater than last consensusState",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -84,7 +84,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"consensus state's valset hash different from evidence should still pass",
|
"consensus state's valset hash different from evidence should still pass",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Height: height - 1, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: suite.valSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -129,7 +129,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid tendermint consensus state",
|
"invalid tendermint consensus state",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
nil,
|
nil,
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
|
||||||
|
@ -144,7 +144,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"invalid tendermint misbehaviour evidence",
|
"invalid tendermint misbehaviour evidence",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
nil,
|
nil,
|
||||||
simapp.DefaultConsensusParams,
|
simapp.DefaultConsensusParams,
|
||||||
|
@ -154,7 +154,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rejected misbehaviour due to expired age",
|
"rejected misbehaviour due to expired age",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -169,7 +169,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"provided height ≠ header height",
|
"provided height ≠ header height",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -184,7 +184,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unbonding period expired",
|
"unbonding period expired",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: time.Time{}, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: time.Time{}, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -199,7 +199,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"first valset has too much change",
|
"first valset has too much change",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
|
||||||
|
@ -214,7 +214,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"second valset has too much change",
|
"second valset has too much change",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
|
||||||
|
@ -229,7 +229,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"both valsets have too much change",
|
"both valsets have too much change",
|
||||||
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
ibctmtypes.ConsensusState{Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), ValidatorSet: bothValSet},
|
||||||
ibctmtypes.Evidence{
|
ibctmtypes.Evidence{
|
||||||
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
|
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
|
||||||
|
|
|
@ -26,6 +26,7 @@ type TendermintTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
cdc *codec.Codec
|
cdc *codec.Codec
|
||||||
|
signers []tmtypes.PrivValidator
|
||||||
privVal tmtypes.PrivValidator
|
privVal tmtypes.PrivValidator
|
||||||
valSet *tmtypes.ValidatorSet
|
valSet *tmtypes.ValidatorSet
|
||||||
header ibctmtypes.Header
|
header ibctmtypes.Header
|
||||||
|
@ -47,15 +48,18 @@ func (suite *TendermintTestSuite) SetupTest() {
|
||||||
// Header time is intended to be time for any new header used for updates
|
// Header time is intended to be time for any new header used for updates
|
||||||
suite.headerTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
|
suite.headerTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
|
||||||
suite.privVal = tmtypes.NewMockPV()
|
suite.privVal = tmtypes.NewMockPV()
|
||||||
|
suite.signers = []tmtypes.PrivValidator{suite.privVal}
|
||||||
|
|
||||||
pubKey, err := suite.privVal.GetPubKey()
|
pubKey, err := suite.privVal.GetPubKey()
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
val := tmtypes.NewValidator(pubKey, 10)
|
val := tmtypes.NewValidator(pubKey, 10)
|
||||||
suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
|
suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
|
||||||
|
|
||||||
// Suite header is intended to be header passed in for initial ClientState
|
// Suite header is intended to be header passed in for initial ClientState
|
||||||
// Thus it should have same height and time as ClientState
|
// Thus it should have same height and time as ClientState
|
||||||
suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, []tmtypes.PrivValidator{suite.privVal})
|
// Note: default header has the same validator set suite.valSet as next validators set
|
||||||
|
suite.header = ibctmtypes.CreateTestHeader(chainID, height, suite.clientTime, suite.valSet, suite.signers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTendermintTestSuite(t *testing.T) {
|
func TestTendermintTestSuite(t *testing.T) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ics23 "github.com/confio/ics23/go"
|
ics23 "github.com/confio/ics23/go"
|
||||||
|
@ -26,6 +27,8 @@ var _ clientexported.ClientState = ClientState{}
|
||||||
// ClientState from Tendermint tracks the current validator set, latest height,
|
// ClientState from Tendermint tracks the current validator set, latest height,
|
||||||
// and a possible frozen height.
|
// and a possible frozen height.
|
||||||
type ClientState struct {
|
type ClientState struct {
|
||||||
|
ChainID string `json:"chain_id" yaml:"chain_id"`
|
||||||
|
|
||||||
TrustLevel tmmath.Fraction `json:"trust_level" yaml:"trust_level"`
|
TrustLevel tmmath.Fraction `json:"trust_level" yaml:"trust_level"`
|
||||||
|
|
||||||
// Duration of the period since the LastestTimestamp during which the
|
// Duration of the period since the LastestTimestamp during which the
|
||||||
|
@ -42,8 +45,8 @@ type ClientState struct {
|
||||||
// Block height when the client was frozen due to a misbehaviour
|
// Block height when the client was frozen due to a misbehaviour
|
||||||
FrozenHeight uint64 `json:"frozen_height" yaml:"frozen_height"`
|
FrozenHeight uint64 `json:"frozen_height" yaml:"frozen_height"`
|
||||||
|
|
||||||
// Last Header that was stored by client
|
// Latest height the client was updated up to
|
||||||
LastHeader Header `json:"last_header" yaml:"last_header"`
|
LatestHeight uint64 `json:"latest_height" yaml:"latest_height"`
|
||||||
|
|
||||||
ProofSpecs []*ics23.ProofSpec `json:"proof_specs" yaml:"proof_specs"`
|
ProofSpecs []*ics23.ProofSpec `json:"proof_specs" yaml:"proof_specs"`
|
||||||
}
|
}
|
||||||
|
@ -51,47 +54,48 @@ type ClientState struct {
|
||||||
// InitializeFromMsg creates a tendermint client state from a CreateClientMsg
|
// InitializeFromMsg creates a tendermint client state from a CreateClientMsg
|
||||||
func InitializeFromMsg(msg *MsgCreateClient) (ClientState, error) {
|
func InitializeFromMsg(msg *MsgCreateClient) (ClientState, error) {
|
||||||
return Initialize(
|
return Initialize(
|
||||||
|
msg.Header.ChainID,
|
||||||
msg.TrustLevel,
|
msg.TrustLevel,
|
||||||
msg.TrustingPeriod, msg.UnbondingPeriod, msg.MaxClockDrift,
|
msg.TrustingPeriod, msg.UnbondingPeriod, msg.MaxClockDrift,
|
||||||
msg.Header, msg.ProofSpecs,
|
uint64(msg.Header.Height), msg.ProofSpecs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize creates a client state and validates its contents, checking that
|
// Initialize creates a client state and validates its contents, checking that
|
||||||
// the provided consensus state is from the same client type.
|
// the provided consensus state is from the same client type.
|
||||||
func Initialize(
|
func Initialize(
|
||||||
|
chainID string,
|
||||||
trustLevel tmmath.Fraction,
|
trustLevel tmmath.Fraction,
|
||||||
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
|
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
|
||||||
header Header, specs []*ics23.ProofSpec,
|
latestHeight uint64, specs []*ics23.ProofSpec,
|
||||||
) (ClientState, error) {
|
) (ClientState, error) {
|
||||||
clientState := NewClientState(trustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, specs)
|
clientState := NewClientState(chainID, trustLevel, trustingPeriod, ubdPeriod, maxClockDrift, latestHeight, specs)
|
||||||
|
|
||||||
return clientState, nil
|
return clientState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientState creates a new ClientState instance
|
// NewClientState creates a new ClientState instance
|
||||||
func NewClientState(
|
func NewClientState(
|
||||||
|
chainID string,
|
||||||
trustLevel tmmath.Fraction,
|
trustLevel tmmath.Fraction,
|
||||||
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
|
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
|
||||||
header Header, specs []*ics23.ProofSpec,
|
latestHeight uint64, specs []*ics23.ProofSpec,
|
||||||
) ClientState {
|
) ClientState {
|
||||||
return ClientState{
|
return ClientState{
|
||||||
|
ChainID: chainID,
|
||||||
TrustLevel: trustLevel,
|
TrustLevel: trustLevel,
|
||||||
TrustingPeriod: trustingPeriod,
|
TrustingPeriod: trustingPeriod,
|
||||||
UnbondingPeriod: ubdPeriod,
|
UnbondingPeriod: ubdPeriod,
|
||||||
MaxClockDrift: maxClockDrift,
|
MaxClockDrift: maxClockDrift,
|
||||||
LastHeader: header,
|
LatestHeight: latestHeight,
|
||||||
FrozenHeight: 0,
|
FrozenHeight: 0,
|
||||||
ProofSpecs: specs,
|
ProofSpecs: specs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetChainID returns the chain-id from the last header
|
// GetChainID returns the chain-id
|
||||||
func (cs ClientState) GetChainID() string {
|
func (cs ClientState) GetChainID() string {
|
||||||
if cs.LastHeader.SignedHeader.Header == nil {
|
return cs.ChainID
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return cs.LastHeader.SignedHeader.Header.ChainID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientType is tendermint.
|
// ClientType is tendermint.
|
||||||
|
@ -101,12 +105,7 @@ func (cs ClientState) ClientType() clientexported.ClientType {
|
||||||
|
|
||||||
// GetLatestHeight returns latest block height.
|
// GetLatestHeight returns latest block height.
|
||||||
func (cs ClientState) GetLatestHeight() uint64 {
|
func (cs ClientState) GetLatestHeight() uint64 {
|
||||||
return uint64(cs.LastHeader.Height)
|
return cs.LatestHeight
|
||||||
}
|
|
||||||
|
|
||||||
// GetLatestTimestamp returns latest block time.
|
|
||||||
func (cs ClientState) GetLatestTimestamp() time.Time {
|
|
||||||
return cs.LastHeader.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsFrozen returns true if the frozen height has been set.
|
// IsFrozen returns true if the frozen height has been set.
|
||||||
|
@ -114,8 +113,17 @@ func (cs ClientState) IsFrozen() bool {
|
||||||
return cs.FrozenHeight != 0
|
return cs.FrozenHeight != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FrozenHeight returns the height at which client is frozen
|
||||||
|
// NOTE: FrozenHeight is 0 if client is unfrozen
|
||||||
|
func (cs ClientState) GetFrozenHeight() uint64 {
|
||||||
|
return cs.FrozenHeight
|
||||||
|
}
|
||||||
|
|
||||||
// Validate performs a basic validation of the client state fields.
|
// Validate performs a basic validation of the client state fields.
|
||||||
func (cs ClientState) Validate() error {
|
func (cs ClientState) Validate() error {
|
||||||
|
if strings.TrimSpace(cs.ChainID) == "" {
|
||||||
|
return sdkerrors.Wrap(ErrInvalidChainID, "chain id cannot be empty string")
|
||||||
|
}
|
||||||
if err := lite.ValidateTrustLevel(cs.TrustLevel); err != nil {
|
if err := lite.ValidateTrustLevel(cs.TrustLevel); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -128,6 +136,9 @@ func (cs ClientState) Validate() error {
|
||||||
if cs.MaxClockDrift == 0 {
|
if cs.MaxClockDrift == 0 {
|
||||||
return sdkerrors.Wrap(ErrInvalidMaxClockDrift, "max clock drift cannot be zero")
|
return sdkerrors.Wrap(ErrInvalidMaxClockDrift, "max clock drift cannot be zero")
|
||||||
}
|
}
|
||||||
|
if cs.LatestHeight == 0 {
|
||||||
|
return sdkerrors.Wrap(ErrInvalidHeaderHeight, "tendermint height cannot be zero")
|
||||||
|
}
|
||||||
if cs.TrustingPeriod >= cs.UnbondingPeriod {
|
if cs.TrustingPeriod >= cs.UnbondingPeriod {
|
||||||
return sdkerrors.Wrapf(
|
return sdkerrors.Wrapf(
|
||||||
ErrInvalidTrustingPeriod,
|
ErrInvalidTrustingPeriod,
|
||||||
|
@ -144,7 +155,7 @@ func (cs ClientState) Validate() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cs.LastHeader.ValidateBasic(cs.GetChainID())
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProofSpecs returns the format the client expects for proof verification
|
// GetProofSpecs returns the format the client expects for proof verification
|
||||||
|
|
|
@ -28,47 +28,52 @@ func (suite *TendermintTestSuite) TestValidate() {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid client",
|
name: "valid client",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: true,
|
expPass: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid chainID",
|
||||||
|
clientState: ibctmtypes.NewClientState(" ", lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
|
expPass: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "invalid trust level",
|
name: "invalid trust level",
|
||||||
clientState: ibctmtypes.NewClientState(tmmath.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, tmmath.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid trusting period",
|
name: "invalid trusting period",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid unbonding period",
|
name: "invalid unbonding period",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid max clock drift",
|
name: "invalid max clock drift",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid header",
|
name: "invalid height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "trusting period not less than unbonding period",
|
name: "trusting period not less than unbonding period",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof specs is nil",
|
name: "proof specs is nil",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, suite.header, nil),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof specs contains nil",
|
name: "proof specs contains nil",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, suite.header, []*ics23.ProofSpec{ics23.TendermintSpec, nil}),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}),
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -95,7 +100,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
|
||||||
// FIXME: uncomment
|
// FIXME: uncomment
|
||||||
// {
|
// {
|
||||||
// name: "successful verification",
|
// name: "successful verification",
|
||||||
// clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
// clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
// consensusState: ibctmtypes.ConsensusState{
|
// consensusState: ibctmtypes.ConsensusState{
|
||||||
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
// },
|
// },
|
||||||
|
@ -104,7 +109,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -113,7 +118,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -122,7 +127,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -131,7 +136,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
ValidatorSet: suite.valSet,
|
ValidatorSet: suite.valSet,
|
||||||
|
@ -173,7 +178,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
|
||||||
// FIXME: uncomment
|
// FIXME: uncomment
|
||||||
// {
|
// {
|
||||||
// name: "successful verification",
|
// name: "successful verification",
|
||||||
// clientState: ibctmtypes.NewClientState(chainID, chainID, height, commitmenttypes.GetSDKSpecs()),
|
// clientState: ibctmtypes.NewClientState(chainID, chainID, chainID, height, commitmenttypes.GetSDKSpecs()),
|
||||||
// connection: conn,
|
// connection: conn,
|
||||||
// consensusState: ibctmtypes.ConsensusState{
|
// consensusState: ibctmtypes.ConsensusState{
|
||||||
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -183,7 +188,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
connection: conn,
|
connection: conn,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -193,7 +198,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
connection: conn,
|
connection: conn,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -203,7 +208,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
connection: conn,
|
connection: conn,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -213,7 +218,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
connection: conn,
|
connection: conn,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -266,7 +271,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
channel: ch,
|
channel: ch,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -276,7 +281,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
channel: ch,
|
channel: ch,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -286,7 +291,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
channel: ch,
|
channel: ch,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -296,7 +301,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
channel: ch,
|
channel: ch,
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -346,7 +351,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
commitment: []byte{},
|
commitment: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -356,7 +361,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
commitment: []byte{},
|
commitment: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -366,7 +371,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
commitment: []byte{},
|
commitment: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -376,7 +381,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
commitment: []byte{},
|
commitment: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -416,7 +421,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
|
||||||
// FIXME: uncomment
|
// FIXME: uncomment
|
||||||
// {
|
// {
|
||||||
// name: "successful verification",
|
// name: "successful verification",
|
||||||
// clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
// clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
// connection: conn,
|
// connection: conn,
|
||||||
// consensusState: ibctmtypes.ConsensusState{
|
// consensusState: ibctmtypes.ConsensusState{
|
||||||
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -426,7 +431,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ack: []byte{},
|
ack: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -436,7 +441,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ack: []byte{},
|
ack: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -446,7 +451,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
ack: []byte{},
|
ack: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -456,7 +461,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
ack: []byte{},
|
ack: []byte{},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
|
@ -505,7 +510,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -514,7 +519,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -523,7 +528,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -532,7 +537,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
ValidatorSet: suite.valSet,
|
ValidatorSet: suite.valSet,
|
||||||
|
@ -580,7 +585,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: "ApplyPrefix failed",
|
name: "ApplyPrefix failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -589,7 +594,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "latest client height < height",
|
name: "latest client height < height",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -598,7 +603,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "client is frozen",
|
name: "client is frozen",
|
||||||
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
|
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
},
|
},
|
||||||
|
@ -607,7 +612,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "proof verification failed",
|
name: "proof verification failed",
|
||||||
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
consensusState: ibctmtypes.ConsensusState{
|
consensusState: ibctmtypes.ConsensusState{
|
||||||
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
|
||||||
ValidatorSet: suite.valSet,
|
ValidatorSet: suite.valSet,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package types
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
@ -13,22 +14,24 @@ import (
|
||||||
|
|
||||||
// ConsensusState defines a Tendermint consensus state
|
// ConsensusState defines a Tendermint consensus state
|
||||||
type ConsensusState struct {
|
type ConsensusState struct {
|
||||||
Timestamp time.Time `json:"timestamp" yaml:"timestamp"`
|
Timestamp time.Time `json:"timestamp" yaml:"timestamp"`
|
||||||
Root commitmentexported.Root `json:"root" yaml:"root"`
|
Root commitmentexported.Root `json:"root" yaml:"root"`
|
||||||
Height uint64 `json:"height" yaml:"height"`
|
Height uint64 `json:"height" yaml:"height"`
|
||||||
ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"`
|
NextValidatorsHash tmbytes.HexBytes `json:"next_validators_hash"` // validators hash for the next block
|
||||||
|
ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConsensusState creates a new ConsensusState instance.
|
// NewConsensusState creates a new ConsensusState instance.
|
||||||
func NewConsensusState(
|
func NewConsensusState(
|
||||||
timestamp time.Time, root commitmentexported.Root, height uint64,
|
timestamp time.Time, root commitmentexported.Root, height uint64,
|
||||||
valset *tmtypes.ValidatorSet,
|
nextValsHash tmbytes.HexBytes, valset *tmtypes.ValidatorSet,
|
||||||
) ConsensusState {
|
) ConsensusState {
|
||||||
return ConsensusState{
|
return ConsensusState{
|
||||||
Timestamp: timestamp,
|
Timestamp: timestamp,
|
||||||
Root: root,
|
Root: root,
|
||||||
Height: height,
|
Height: height,
|
||||||
ValidatorSet: valset,
|
NextValidatorsHash: nextValsHash,
|
||||||
|
ValidatorSet: valset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +63,9 @@ func (cs ConsensusState) ValidateBasic() error {
|
||||||
if cs.ValidatorSet == nil {
|
if cs.ValidatorSet == nil {
|
||||||
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "validator set cannot be nil")
|
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "validator set cannot be nil")
|
||||||
}
|
}
|
||||||
|
if err := tmtypes.ValidateHash(cs.NextValidatorsHash); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "next validators hash is invalid")
|
||||||
|
}
|
||||||
if cs.Height == 0 {
|
if cs.Height == 0 {
|
||||||
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "height cannot be 0")
|
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "height cannot be 0")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,13 @@ const (
|
||||||
|
|
||||||
// IBC tendermint client sentinel errors
|
// IBC tendermint client sentinel errors
|
||||||
var (
|
var (
|
||||||
ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 2, "invalid trusting period")
|
ErrInvalidChainID = sdkerrors.Register(SubModuleName, 2, "invalid chain-id")
|
||||||
ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 3, "invalid unbonding period")
|
ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 3, "invalid trusting period")
|
||||||
ErrInvalidHeader = sdkerrors.Register(SubModuleName, 4, "invalid header")
|
ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 4, "invalid unbonding period")
|
||||||
ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 5, "invalid max clock drift")
|
ErrInvalidHeaderHeight = sdkerrors.Register(SubModuleName, 5, "invalid header height")
|
||||||
ErrTrustingPeriodExpired = sdkerrors.Register(SubModuleName, 6, "time since latest trusted state has passed the trusting period")
|
ErrInvalidHeader = sdkerrors.Register(SubModuleName, 6, "invalid header")
|
||||||
ErrUnbondingPeriodExpired = sdkerrors.Register(SubModuleName, 7, "time since latest trusted state has passed the unbonding period")
|
ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 7, "invalid max clock drift")
|
||||||
ErrInvalidProofSpecs = sdkerrors.Register(SubModuleName, 8, "invalid proof specs")
|
ErrTrustingPeriodExpired = sdkerrors.Register(SubModuleName, 8, "time since latest trusted state has passed the trusting period")
|
||||||
|
ErrUnbondingPeriodExpired = sdkerrors.Register(SubModuleName, 9, "time since latest trusted state has passed the unbonding period")
|
||||||
|
ErrInvalidProofSpecs = sdkerrors.Register(SubModuleName, 10, "invalid proof specs")
|
||||||
)
|
)
|
||||||
|
|
|
@ -142,10 +142,11 @@ func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState {
|
||||||
// Construct initial consensus state from provided Header
|
// Construct initial consensus state from provided Header
|
||||||
root := commitmenttypes.NewMerkleRoot(msg.Header.AppHash)
|
root := commitmenttypes.NewMerkleRoot(msg.Header.AppHash)
|
||||||
return ConsensusState{
|
return ConsensusState{
|
||||||
Timestamp: msg.Header.Time,
|
Timestamp: msg.Header.Time,
|
||||||
Root: root,
|
Root: root,
|
||||||
Height: uint64(msg.Header.Height),
|
Height: uint64(msg.Header.Height),
|
||||||
ValidatorSet: msg.Header.ValidatorSet,
|
NextValidatorsHash: msg.Header.NextValidatorsHash,
|
||||||
|
ValidatorSet: msg.Header.ValidatorSet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
lite "github.com/tendermint/tendermint/lite2"
|
lite "github.com/tendermint/tendermint/lite2"
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
|
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
|
||||||
|
@ -12,18 +13,28 @@ import (
|
||||||
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
|
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckValidityAndUpdateState checks if the provided header is valid and updates
|
// CheckValidityAndUpdateState checks if the provided header is valid, and if valid it will:
|
||||||
// the consensus state if appropriate. It returns an error if:
|
// create the consensus state for the header.Height
|
||||||
|
// and update the client state if the header height is greater than the latest client state height
|
||||||
|
// It returns an error if:
|
||||||
// - the client or header provided are not parseable to tendermint types
|
// - the client or header provided are not parseable to tendermint types
|
||||||
// - the header is invalid
|
// - the header is invalid
|
||||||
// - header height is lower than the latest client height
|
// - header height is less than or equal to the consensus state height
|
||||||
// - header valset commit verification fails
|
// - header valset commit verification fails
|
||||||
|
// - header timestamp is past the trusting period in relation to the consensus state
|
||||||
|
// - header timestamp is less than or equal to the consensus state timestamp
|
||||||
//
|
//
|
||||||
|
// UpdateClient may be used to either create a consensus state for:
|
||||||
|
// - a future height greater than the latest client state height
|
||||||
|
// - a past height that was skipped during bisection
|
||||||
|
// If we are updating to a past height, a consensus state is created for that height to be persisted in client store
|
||||||
|
// If we are updating to a future height, the consensus state is created and the client state is updated to reflect
|
||||||
|
// the new latest height
|
||||||
// Tendermint client validity checking uses the bisection algorithm described
|
// Tendermint client validity checking uses the bisection algorithm described
|
||||||
// in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md).
|
// in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md).
|
||||||
func CheckValidityAndUpdateState(
|
func CheckValidityAndUpdateState(
|
||||||
clientState clientexported.ClientState, header clientexported.Header,
|
clientState clientexported.ClientState, consState clientexported.ConsensusState,
|
||||||
currentTimestamp time.Time,
|
header clientexported.Header, currentTimestamp time.Time,
|
||||||
) (clientexported.ClientState, clientexported.ConsensusState, error) {
|
) (clientexported.ClientState, clientexported.ConsensusState, error) {
|
||||||
tmClientState, ok := clientState.(types.ClientState)
|
tmClientState, ok := clientState.(types.ClientState)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -32,6 +43,13 @@ func CheckValidityAndUpdateState(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmConsState, ok := consState.(types.ConsensusState)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, sdkerrors.Wrapf(
|
||||||
|
clienttypes.ErrInvalidConsensus, "expected type %T, got %T", types.ConsensusState{}, consState,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
tmHeader, ok := header.(types.Header)
|
tmHeader, ok := header.(types.Header)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, sdkerrors.Wrapf(
|
return nil, nil, sdkerrors.Wrapf(
|
||||||
|
@ -39,7 +57,7 @@ func CheckValidityAndUpdateState(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkValidity(tmClientState, tmHeader, currentTimestamp); err != nil {
|
if err := checkValidity(tmClientState, tmConsState, tmHeader, currentTimestamp); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,49 +66,58 @@ func CheckValidityAndUpdateState(
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkValidity checks if the Tendermint header is valid.
|
// checkValidity checks if the Tendermint header is valid.
|
||||||
//
|
|
||||||
// CONTRACT: assumes header.Height > consensusState.Height
|
|
||||||
func checkValidity(
|
func checkValidity(
|
||||||
clientState types.ClientState, header types.Header, currentTimestamp time.Time,
|
clientState types.ClientState, consState types.ConsensusState, header types.Header, currentTimestamp time.Time,
|
||||||
) error {
|
) error {
|
||||||
// assert trusting period has not yet passed
|
// assert trusting period has not yet passed
|
||||||
if currentTimestamp.Sub(clientState.GetLatestTimestamp()) >= clientState.TrustingPeriod {
|
if currentTimestamp.Sub(consState.Timestamp) >= clientState.TrustingPeriod {
|
||||||
return sdkerrors.Wrapf(
|
return sdkerrors.Wrapf(
|
||||||
types.ErrTrustingPeriodExpired,
|
types.ErrTrustingPeriodExpired,
|
||||||
"current timestamp minus the latest trusted client state timestamp is greater than or equal to the trusting period (%s >= %s)",
|
"current timestamp minus the consensus state timestamp is greater than or equal to the trusting period (%s >= %s)",
|
||||||
currentTimestamp.Sub(clientState.GetLatestTimestamp()), clientState.TrustingPeriod,
|
currentTimestamp.Sub(consState.Timestamp), clientState.TrustingPeriod,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert header timestamp is not past the trusting period
|
// assert header timestamp is not past the trusting period
|
||||||
if header.Time.Sub(clientState.GetLatestTimestamp()) >= clientState.TrustingPeriod {
|
if header.Time.Sub(consState.Timestamp) >= clientState.TrustingPeriod {
|
||||||
return sdkerrors.Wrap(
|
return sdkerrors.Wrap(
|
||||||
clienttypes.ErrInvalidHeader,
|
clienttypes.ErrInvalidHeader,
|
||||||
"header blocktime is outside trusting period from last client timestamp",
|
"header timestamp is beyond trusting period in relation to the consensus state timestamp",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert header timestamp is past latest clientstate timestamp
|
// assert header timestamp is past latest stored consensus state timestamp
|
||||||
if header.Time.Unix() <= clientState.GetLatestTimestamp().Unix() {
|
if header.Time.Unix() <= consState.Timestamp.Unix() {
|
||||||
return sdkerrors.Wrapf(
|
return sdkerrors.Wrapf(
|
||||||
clienttypes.ErrInvalidHeader,
|
clienttypes.ErrInvalidHeader,
|
||||||
"header blocktime ≤ latest client state block time (%s ≤ %s)",
|
"header timestamp ≤ consensus state timestamp (%s ≤ %s)",
|
||||||
header.Time.UTC(), clientState.GetLatestTimestamp().UTC(),
|
header.Time.UTC(), consState.Timestamp.UTC(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert header height is newer than any we know
|
// assert header height is newer than consensus state
|
||||||
if header.GetHeight() <= clientState.GetLatestHeight() {
|
if header.GetHeight() <= consState.Height {
|
||||||
return sdkerrors.Wrapf(
|
return sdkerrors.Wrapf(
|
||||||
clienttypes.ErrInvalidHeader,
|
clienttypes.ErrInvalidHeader,
|
||||||
"header height ≤ latest client state height (%d ≤ %d)", header.GetHeight(), clientState.GetLatestHeight(),
|
"header height ≤ consensus state height (%d ≤ %d)", header.GetHeight(), consState.Height,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Construct a trusted header using the fields in consensus state
|
||||||
|
// Only Height, Time, and NextValidatorsHash are necessary for verification
|
||||||
|
trustedHeader := tmtypes.Header{
|
||||||
|
Height: int64(consState.Height),
|
||||||
|
Time: consState.Timestamp,
|
||||||
|
NextValidatorsHash: consState.NextValidatorsHash,
|
||||||
|
}
|
||||||
|
signedHeader := tmtypes.SignedHeader{
|
||||||
|
Header: &trustedHeader,
|
||||||
|
}
|
||||||
|
|
||||||
// Verify next header with the last header's validatorset as trusted validatorset
|
// Verify next header with the last header's validatorset as trusted validatorset
|
||||||
err := lite.Verify(
|
err := lite.Verify(
|
||||||
clientState.GetChainID(), &clientState.LastHeader.SignedHeader,
|
clientState.GetChainID(), &signedHeader,
|
||||||
clientState.LastHeader.ValidatorSet, &header.SignedHeader, header.ValidatorSet,
|
consState.ValidatorSet, &header.SignedHeader, header.ValidatorSet,
|
||||||
clientState.TrustingPeriod, currentTimestamp, clientState.MaxClockDrift, clientState.TrustLevel,
|
clientState.TrustingPeriod, currentTimestamp, clientState.MaxClockDrift, clientState.TrustLevel,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,12 +128,15 @@ func checkValidity(
|
||||||
|
|
||||||
// update the consensus state from a new header
|
// update the consensus state from a new header
|
||||||
func update(clientState types.ClientState, header types.Header) (types.ClientState, types.ConsensusState) {
|
func update(clientState types.ClientState, header types.Header) (types.ClientState, types.ConsensusState) {
|
||||||
clientState.LastHeader = header
|
if uint64(header.Height) > clientState.LatestHeight {
|
||||||
|
clientState.LatestHeight = uint64(header.Height)
|
||||||
|
}
|
||||||
consensusState := types.ConsensusState{
|
consensusState := types.ConsensusState{
|
||||||
Height: uint64(header.Height),
|
Height: uint64(header.Height),
|
||||||
Timestamp: header.Time,
|
Timestamp: header.Time,
|
||||||
Root: commitmenttypes.NewMerkleRoot(header.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(header.AppHash),
|
||||||
ValidatorSet: header.ValidatorSet,
|
NextValidatorsHash: header.NextValidatorsHash,
|
||||||
|
ValidatorSet: header.ValidatorSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientState, consensusState
|
return clientState, consensusState
|
||||||
|
|
|
@ -14,9 +14,10 @@ import (
|
||||||
|
|
||||||
func (suite *TendermintTestSuite) TestCheckValidity() {
|
func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
var (
|
var (
|
||||||
clientState ibctmtypes.ClientState
|
clientState ibctmtypes.ClientState
|
||||||
newHeader ibctmtypes.Header
|
consensusState ibctmtypes.ConsensusState
|
||||||
currentTime time.Time
|
newHeader ibctmtypes.Header
|
||||||
|
currentTime time.Time
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup different validators and signers for testing different types of updates
|
// Setup different validators and signers for testing different types of updates
|
||||||
|
@ -54,7 +55,8 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
{
|
{
|
||||||
name: "successful update with next height and same validator set",
|
name: "successful update with next height and same validator set",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
|
@ -63,25 +65,58 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
{
|
{
|
||||||
name: "successful update with future height and different validator set",
|
name: "successful update with future height and different validator set",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, bothValSet, bothSigners)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, bothValSet, bothSigners)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
expPass: true,
|
expPass: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "successful update with next height and different validator set",
|
||||||
|
setup: func() {
|
||||||
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, bothValSet.Hash(), suite.valSet)
|
||||||
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothSigners)
|
||||||
|
currentTime = suite.now
|
||||||
|
},
|
||||||
|
expPass: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "successful update for a previous height",
|
||||||
|
setup: func() {
|
||||||
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height-3, bothValSet.Hash(), suite.valSet)
|
||||||
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, bothValSet, bothSigners)
|
||||||
|
currentTime = suite.now
|
||||||
|
},
|
||||||
|
expPass: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "unsuccessful update with next height: update header mismatches nextValSetHash",
|
name: "unsuccessful update with next height: update header mismatches nextValSetHash",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothSigners)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, bothValSet, bothSigners)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "unsuccessful update with next height: update header mismatches different nextValSetHash",
|
||||||
|
setup: func() {
|
||||||
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, bothValSet.Hash(), suite.valSet)
|
||||||
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
||||||
|
currentTime = suite.now
|
||||||
|
},
|
||||||
|
expPass: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "unsuccessful update with future height: too much change in validator set",
|
name: "unsuccessful update with future height: too much change in validator set",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, altValSet, altSigners)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+5, suite.headerTime, altValSet, altSigners)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
|
@ -90,17 +125,19 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
{
|
{
|
||||||
name: "unsuccessful update: trusting period has passed since last client timestamp",
|
name: "unsuccessful update: trusting period has passed since last client timestamp",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
||||||
// make current time pass trusting period from last timestamp on clientstate
|
// make current time pass trusting period from last timestamp on clientstate
|
||||||
currentTime = suite.now.Add(ubdPeriod)
|
currentTime = suite.now.Add(trustingPeriod)
|
||||||
},
|
},
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unsuccessful update: header timestamp is past current timestamp",
|
name: "unsuccessful update: header timestamp is past current timestamp",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.now.Add(time.Minute), suite.valSet, signers)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.now.Add(time.Minute), suite.valSet, signers)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
|
@ -109,7 +146,8 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
{
|
{
|
||||||
name: "unsuccessful update: header timestamp is not past last client timestamp",
|
name: "unsuccessful update: header timestamp is not past last client timestamp",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.clientTime, suite.valSet, signers)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.clientTime, suite.valSet, signers)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
|
@ -118,7 +156,8 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
{
|
{
|
||||||
name: "header basic validation failed",
|
name: "header basic validation failed",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height+1, suite.headerTime, suite.valSet, signers)
|
||||||
// cause new header to fail validatebasic by changing commit height to mismatch header height
|
// cause new header to fail validatebasic by changing commit height to mismatch header height
|
||||||
newHeader.SignedHeader.Commit.Height = height - 1
|
newHeader.SignedHeader.Commit.Height = height - 1
|
||||||
|
@ -127,14 +166,14 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "header height < latest client height",
|
name: "header height < consensus height",
|
||||||
setup: func() {
|
setup: func() {
|
||||||
clientState = ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs())
|
clientState = ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height+5, commitmenttypes.GetSDKSpecs())
|
||||||
|
consensusState = ibctmtypes.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valSet.Hash(), suite.valSet)
|
||||||
// Make new header at height less than latest client state
|
// Make new header at height less than latest client state
|
||||||
newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, suite.valSet, signers)
|
newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, suite.valSet, signers)
|
||||||
currentTime = suite.now
|
currentTime = suite.now
|
||||||
},
|
},
|
||||||
|
|
||||||
expPass: false,
|
expPass: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -145,21 +184,31 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
|
||||||
tc.setup()
|
tc.setup()
|
||||||
|
|
||||||
expectedConsensus := ibctmtypes.ConsensusState{
|
expectedConsensus := ibctmtypes.ConsensusState{
|
||||||
Height: uint64(newHeader.Height),
|
Height: uint64(newHeader.Height),
|
||||||
Timestamp: newHeader.Time,
|
Timestamp: newHeader.Time,
|
||||||
Root: commitmenttypes.NewMerkleRoot(newHeader.AppHash),
|
Root: commitmenttypes.NewMerkleRoot(newHeader.AppHash),
|
||||||
ValidatorSet: newHeader.ValidatorSet,
|
NextValidatorsHash: newHeader.NextValidatorsHash,
|
||||||
|
ValidatorSet: newHeader.ValidatorSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
clientState, consensusState, err := tendermint.CheckValidityAndUpdateState(clientState, newHeader, currentTime)
|
newClientState, consensusState, err := tendermint.CheckValidityAndUpdateState(clientState, consensusState, newHeader, currentTime)
|
||||||
|
|
||||||
if tc.expPass {
|
if tc.expPass {
|
||||||
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name)
|
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name)
|
||||||
suite.Require().Equal(newHeader.GetHeight(), clientState.GetLatestHeight(), "valid test case %d failed: %s", i, tc.name)
|
|
||||||
|
// Determine if clientState should be updated or not
|
||||||
|
if uint64(newHeader.Height) > clientState.LatestHeight {
|
||||||
|
// Header Height is greater than clientState latest Height, clientState should be updated with header.Height
|
||||||
|
suite.Require().Equal(uint64(newHeader.Height), newClientState.GetLatestHeight(), "clientstate height did not update")
|
||||||
|
} else {
|
||||||
|
// Update will add past consensus state, clientState should not be updated at all
|
||||||
|
suite.Require().Equal(clientState.LatestHeight, newClientState.GetLatestHeight(), "client state height updated for past header")
|
||||||
|
}
|
||||||
|
|
||||||
suite.Require().Equal(expectedConsensus, consensusState, "valid test case %d failed: %s", i, tc.name)
|
suite.Require().Equal(expectedConsensus, consensusState, "valid test case %d failed: %s", i, tc.name)
|
||||||
} else {
|
} else {
|
||||||
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name)
|
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name)
|
||||||
suite.Require().Nil(clientState, "invalid test case %d passed: %s", i, tc.name)
|
suite.Require().Nil(newClientState, "invalid test case %d passed: %s", i, tc.name)
|
||||||
suite.Require().Nil(consensusState, "invalid test case %d passed: %s", i, tc.name)
|
suite.Require().Nil(consensusState, "invalid test case %d passed: %s", i, tc.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,11 @@ func (cs ClientState) IsFrozen() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFrozenHeight returns 0.
|
||||||
|
func (cs ClientState) GetFrozenHeight() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// Validate performs a basic validation of the client state fields.
|
// Validate performs a basic validation of the client state fields.
|
||||||
func (cs ClientState) Validate() error {
|
func (cs ClientState) Validate() error {
|
||||||
if strings.TrimSpace(cs.ChainID) == "" {
|
if strings.TrimSpace(cs.ChainID) == "" {
|
||||||
|
|
|
@ -32,7 +32,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
|
||||||
ClientGenesis: clienttypes.NewGenesisState(
|
ClientGenesis: clienttypes.NewGenesisState(
|
||||||
[]clienttypes.GenesisClientState{
|
[]clienttypes.GenesisClientState{
|
||||||
clienttypes.NewGenesisClientState(
|
clienttypes.NewGenesisClientState(
|
||||||
clientID, ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientID, ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
clienttypes.NewGenesisClientState(
|
clienttypes.NewGenesisClientState(
|
||||||
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
|
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
|
||||||
|
@ -43,7 +43,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
|
||||||
clientID,
|
clientID,
|
||||||
[]exported.ConsensusState{
|
[]exported.ConsensusState{
|
||||||
ibctmtypes.NewConsensusState(
|
ibctmtypes.NewConsensusState(
|
||||||
suite.header.Time, commitmenttypes.NewMerkleRoot(suite.header.AppHash), suite.header.GetHeight(), suite.header.ValidatorSet,
|
suite.header.Time, commitmenttypes.NewMerkleRoot(suite.header.AppHash), suite.header.GetHeight(), suite.header.ValidatorSet.Hash(), suite.header.ValidatorSet,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -92,7 +92,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
|
||||||
ClientGenesis: clienttypes.NewGenesisState(
|
ClientGenesis: clienttypes.NewGenesisState(
|
||||||
[]clienttypes.GenesisClientState{
|
[]clienttypes.GenesisClientState{
|
||||||
clienttypes.NewGenesisClientState(
|
clienttypes.NewGenesisClientState(
|
||||||
clientID, ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, suite.header, commitmenttypes.GetSDKSpecs()),
|
clientID, ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
|
||||||
),
|
),
|
||||||
clienttypes.NewGenesisClientState(
|
clienttypes.NewGenesisClientState(
|
||||||
exported.ClientTypeLocalHost, localhosttypes.NewClientState("(chaindID)", 0),
|
exported.ClientTypeLocalHost, localhosttypes.NewClientState("(chaindID)", 0),
|
||||||
|
|
|
@ -17,6 +17,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
chainID = "chainID"
|
||||||
|
|
||||||
connectionID = "connectionidone"
|
connectionID = "connectionidone"
|
||||||
clientID = "clientidone"
|
clientID = "clientidone"
|
||||||
connectionID2 = "connectionidtwo"
|
connectionID2 = "connectionidtwo"
|
||||||
|
@ -31,6 +33,8 @@ const (
|
||||||
channelOrder = channeltypes.ORDERED
|
channelOrder = channeltypes.ORDERED
|
||||||
channelVersion = "1.0"
|
channelVersion = "1.0"
|
||||||
|
|
||||||
|
height = 10
|
||||||
|
|
||||||
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2
|
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2
|
||||||
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3
|
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3
|
||||||
maxClockDrift time.Duration = time.Second * 10
|
maxClockDrift time.Duration = time.Second * 10
|
||||||
|
@ -58,7 +62,7 @@ func (suite *IBCTestSuite) SetupTest() {
|
||||||
val := tmtypes.NewValidator(pubKey, 10)
|
val := tmtypes.NewValidator(pubKey, 10)
|
||||||
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
|
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
|
||||||
|
|
||||||
suite.header = ibctmtypes.CreateTestHeader("chainID", 10, now, valSet, []tmtypes.PrivValidator{privVal})
|
suite.header = ibctmtypes.CreateTestHeader(chainID, height, now, valSet, []tmtypes.PrivValidator{privVal})
|
||||||
|
|
||||||
suite.cdc = suite.app.Codec()
|
suite.cdc = suite.app.Codec()
|
||||||
suite.ctx = suite.app.BaseApp.NewContext(isCheckTx, abci.Header{})
|
suite.ctx = suite.app.BaseApp.NewContext(isCheckTx, abci.Header{})
|
||||||
|
|
|
@ -202,7 +202,9 @@ func (chain *TestChain) NextBlock() {
|
||||||
AppHash: chain.App.LastCommitID().Hash,
|
AppHash: chain.App.LastCommitID().Hash,
|
||||||
// NOTE: the time is increased by the coordinator to maintain time synchrony amongst
|
// NOTE: the time is increased by the coordinator to maintain time synchrony amongst
|
||||||
// chains.
|
// chains.
|
||||||
Time: chain.CurrentHeader.Time,
|
Time: chain.CurrentHeader.Time,
|
||||||
|
ValidatorsHash: chain.Vals.Hash(),
|
||||||
|
NextValidatorsHash: chain.Vals.Hash(),
|
||||||
}
|
}
|
||||||
|
|
||||||
chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader})
|
chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader})
|
||||||
|
|
Loading…
Reference in New Issue