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:
Aditya 2020-08-04 05:05:03 -04:00 committed by GitHub
parent 0daf3c3271
commit 9b61e0947e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 419 additions and 215 deletions

View File

@ -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
} }

View File

@ -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

View File

@ -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(

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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{},
), ),
}, },
), ),

View File

@ -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,
), ),
}, },
), ),

View File

@ -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),

View File

@ -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) {

View File

@ -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

View File

@ -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,

View File

@ -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")
} }

View File

@ -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")
) )

View File

@ -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,
} }
} }

View File

@ -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

View File

@ -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)
} }
} }

View File

@ -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) == "" {

View File

@ -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),

View File

@ -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{})

View File

@ -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})