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

View File

@ -21,6 +21,7 @@ type ClientState interface {
ClientType() ClientType
GetLatestHeight() uint64
IsFrozen() bool
GetFrozenHeight() uint64
Validate() error
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)
}
// addition to spec: prevent update if the client is frozen
if clientState.IsFrozen() {
// prevent update if the client is frozen before or at header height
if clientState.IsFrozen() && clientState.GetFrozenHeight() <= header.GetHeight() {
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 {
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, 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:
// override client state and update the block height
clientState = localhosttypes.NewClientState(

View File

@ -38,12 +38,12 @@ func (suite *KeeperTestSuite) TestCreateClient() {
i := i
if tc.expPanic {
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.keeper.CreateClient(suite.ctx, tc.clientID, clientState, suite.consensusState)
}, "Msg %d didn't panic: %s", i, tc.msg)
} 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 {
suite.Require().NoError(err, "errored on initialization")
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() {
// Must create header creation functions since suite.header gets recreated on each test case
createValidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height+1, suite.header.Time.Add(time.Minute),
createFutureUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
return ibctmtypes.CreateTestHeader(testChainID, suite.header.Height+1, suite.header.Time.Add(time.Minute),
suite.valSet, []tmtypes.PrivValidator{suite.privVal})
}
createInvalidUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
return ibctmtypes.CreateTestHeader(testClientID, suite.header.Height-3, suite.header.Time.Add(time.Minute),
createPastUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
return ibctmtypes.CreateTestHeader(testChainID, suite.header.Height-3, suite.header.Time,
suite.valSet, []tmtypes.PrivValidator{suite.privVal})
}
var updateHeader ibctmtypes.Header
var (
updateHeader ibctmtypes.Header
clientState ibctmtypes.ClientState
err error
)
cases := []struct {
name string
@ -80,41 +84,95 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
expPass bool
}{
{"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 {
return err
}
_, err = suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
updateHeader = createValidUpdateFn(suite)
updateHeader = createFutureUpdateFn(suite)
return err
}, 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 {
updateHeader = createValidUpdateFn(suite)
updateHeader = createFutureUpdateFn(suite)
return nil
}, false},
{"client type and header type mismatch", func() error {
suite.keeper.SetClientType(suite.ctx, testClientID, invalidClientType)
updateHeader = createValidUpdateFn(suite)
updateHeader = createFutureUpdateFn(suite)
return nil
}, false},
{"client state not found", func() error {
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
updateHeader = createValidUpdateFn(suite)
updateHeader = createFutureUpdateFn(suite)
return nil
}, false},
{"frozen client", func() error {
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LastHeader: suite.header}
{"consensus state not found", func() error {
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.SetClientType(suite.ctx, testClientID, exported.Tendermint)
updateHeader = createValidUpdateFn(suite)
updateHeader = createFutureUpdateFn(suite)
return nil
}, 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 {
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 {
return err
}
@ -122,7 +180,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
if err != nil {
return err
}
updateHeader = createInvalidUpdateFn(suite)
updateHeader = createPastUpdateFn(suite)
return nil
}, false},
@ -145,13 +203,14 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
suite.Require().NoError(err, err)
expConsensusState := ibctmtypes.ConsensusState{
Height: updateHeader.GetHeight(),
Timestamp: updateHeader.Time,
Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash),
ValidatorSet: updateHeader.ValidatorSet,
Height: updateHeader.GetHeight(),
Timestamp: updateHeader.Time,
Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash),
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)
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
tmConsState.ValidatorSet.TotalVotingPower()
tmClientState, ok := updatedClientState.(ibctmtypes.ClientState)
suite.Require().True(ok, "client state is not a tendermint client state")
// check returned client state is same as client state in store
suite.Require().Equal(updatedClientState, newClientState, "updatedClient state not persisted correctly")
// recalculate cached totalVotingPower field for equality check
tmClientState.LastHeader.ValidatorSet.TotalVotingPower()
// Determine if clientState should be updated or not
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().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(updatedClientState, tmClientState, "client states don't match")
} else {
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name)
}
@ -228,7 +291,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
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 {
return err
}
@ -248,7 +311,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
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 {
return err
}
@ -273,7 +336,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
ClientID: testClientID,
},
func() error {
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LastHeader: suite.header}
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
return nil
},
@ -288,7 +351,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
ClientID: testClientID,
},
func() error {
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LastHeader: suite.header}
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
return nil
},
@ -303,7 +366,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
ClientID: testClientID,
},
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 {
return err
}

View File

@ -211,10 +211,11 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported.
valSet := stakingtypes.Validators(histInfo.Valset)
consensusState := ibctmtypes.ConsensusState{
Height: height,
Timestamp: histInfo.Header.Time,
Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash),
ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()),
Height: height,
Timestamp: histInfo.Header.Time,
Root: commitmenttypes.NewMerkleRoot(histInfo.Header.AppHash),
NextValidatorsHash: histInfo.Header.NextValidatorsHash,
ValidatorSet: tmtypes.NewValidatorSet(valSet.ToTmValidators()),
}
return consensusState, true
}

View File

@ -23,6 +23,8 @@ import (
)
const (
testChainID = "gaiahub"
testClientID = "gaiachain"
testClientID2 = "ethbridge"
testClientID3 = "ethermint"
@ -45,11 +47,13 @@ type KeeperTestSuite struct {
valSet *tmtypes.ValidatorSet
privVal tmtypes.PrivValidator
now time.Time
past time.Time
}
func (suite *KeeperTestSuite) SetupTest() {
isCheckTx := false
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)
app := simapp.Setup(isCheckTx)
@ -63,12 +67,13 @@ func (suite *KeeperTestSuite) SetupTest() {
validator := tmtypes.NewValidator(pubKey, 1)
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{
Height: testClientHeight,
Timestamp: suite.now,
Root: commitmenttypes.NewMerkleRoot([]byte("hash")),
ValidatorSet: suite.valSet,
Height: testClientHeight,
Timestamp: suite.now,
Root: commitmenttypes.NewMerkleRoot([]byte("hash")),
NextValidatorsHash: suite.valSet.Hash(),
ValidatorSet: suite.valSet,
}
var validators stakingtypes.Validators
@ -90,7 +95,7 @@ func TestKeeperTestSuite(t *testing.T) {
}
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)
retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
@ -124,9 +129,9 @@ func (suite KeeperTestSuite) TestGetAllClients() {
testClientID2, testClientID3, testClientID,
}
expClients := []exported.ClientState{
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, 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(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
}
for i := range expClients {
@ -148,9 +153,9 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() {
testClientID2, testClientID3, testClientID,
}
expClients := []exported.ClientState{
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, 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(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
ibctmtypes.NewClientState(testChainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
}
expGenClients := make([]types.GenesisClientState, len(expClients))
@ -198,7 +203,7 @@ func (suite KeeperTestSuite) TestGetConsensusState() {
func (suite KeeperTestSuite) TestConsensusStateHelpers() {
// 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.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})
// mock update functionality
clientState.LastHeader = header
clientState.LatestHeight = uint64(header.Height)
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+5, nextState)
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
@ -238,10 +243,10 @@ func (suite KeeperTestSuite) TestGetAllConsensusStates() {
testClientID,
[]exported.ConsensusState{
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(
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,
[]exported.ConsensusState{
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 (
chainID = "chainID"
clientID = "ethbridge"
height = 10
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3
maxClockDrift time.Duration = time.Second * 10
@ -34,7 +37,7 @@ func TestValidateGenesis(t *testing.T) {
val := tmtypes.NewValidator(pubKey, 10)
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 {
name string
@ -51,7 +54,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.GenesisClientState{
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("chainID", 10),
@ -62,7 +65,7 @@ func TestValidateGenesis(t *testing.T) {
clientID,
[]exported.ConsensusState{
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(
[]types.GenesisClientState{
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(
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10),
@ -87,7 +90,7 @@ func TestValidateGenesis(t *testing.T) {
clientID,
[]exported.ConsensusState{
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(
[]types.GenesisClientState{
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)),
},
@ -116,7 +119,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.GenesisClientState{
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", 10),
@ -127,7 +130,7 @@ func TestValidateGenesis(t *testing.T) {
"CLIENTID2",
[]exported.ConsensusState{
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(
[]types.GenesisClientState{
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", 10),
@ -152,7 +155,7 @@ func TestValidateGenesis(t *testing.T) {
clientID,
[]exported.ConsensusState{
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",
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.Evidence{
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",
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.Evidence{
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",
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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
@ -129,7 +129,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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,
ibctmtypes.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
@ -144,7 +144,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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},
nil,
simapp.DefaultConsensusParams,
@ -154,7 +154,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
@ -169,7 +169,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
@ -184,7 +184,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
@ -199,7 +199,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),
@ -214,7 +214,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, bothValSet, bothSigners),
@ -229,7 +229,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviour() {
},
{
"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.Evidence{
Header1: ibctmtypes.CreateTestHeader(chainID, height, suite.now, altValSet, altSigners),

View File

@ -26,6 +26,7 @@ type TendermintTestSuite struct {
suite.Suite
cdc *codec.Codec
signers []tmtypes.PrivValidator
privVal tmtypes.PrivValidator
valSet *tmtypes.ValidatorSet
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
suite.headerTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
suite.privVal = tmtypes.NewMockPV()
suite.signers = []tmtypes.PrivValidator{suite.privVal}
pubKey, err := suite.privVal.GetPubKey()
suite.Require().NoError(err)
val := tmtypes.NewValidator(pubKey, 10)
suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val})
// Suite header is intended to be header passed in for initial 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) {

View File

@ -1,6 +1,7 @@
package types
import (
"strings"
"time"
ics23 "github.com/confio/ics23/go"
@ -26,6 +27,8 @@ var _ clientexported.ClientState = ClientState{}
// ClientState from Tendermint tracks the current validator set, latest height,
// and a possible frozen height.
type ClientState struct {
ChainID string `json:"chain_id" yaml:"chain_id"`
TrustLevel tmmath.Fraction `json:"trust_level" yaml:"trust_level"`
// 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
FrozenHeight uint64 `json:"frozen_height" yaml:"frozen_height"`
// Last Header that was stored by client
LastHeader Header `json:"last_header" yaml:"last_header"`
// Latest height the client was updated up to
LatestHeight uint64 `json:"latest_height" yaml:"latest_height"`
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
func InitializeFromMsg(msg *MsgCreateClient) (ClientState, error) {
return Initialize(
msg.Header.ChainID,
msg.TrustLevel,
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
// the provided consensus state is from the same client type.
func Initialize(
chainID string,
trustLevel tmmath.Fraction,
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
header Header, specs []*ics23.ProofSpec,
latestHeight uint64, specs []*ics23.ProofSpec,
) (ClientState, error) {
clientState := NewClientState(trustLevel, trustingPeriod, ubdPeriod, maxClockDrift, header, specs)
clientState := NewClientState(chainID, trustLevel, trustingPeriod, ubdPeriod, maxClockDrift, latestHeight, specs)
return clientState, nil
}
// NewClientState creates a new ClientState instance
func NewClientState(
chainID string,
trustLevel tmmath.Fraction,
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
header Header, specs []*ics23.ProofSpec,
latestHeight uint64, specs []*ics23.ProofSpec,
) ClientState {
return ClientState{
ChainID: chainID,
TrustLevel: trustLevel,
TrustingPeriod: trustingPeriod,
UnbondingPeriod: ubdPeriod,
MaxClockDrift: maxClockDrift,
LastHeader: header,
LatestHeight: latestHeight,
FrozenHeight: 0,
ProofSpecs: specs,
}
}
// GetChainID returns the chain-id from the last header
// GetChainID returns the chain-id
func (cs ClientState) GetChainID() string {
if cs.LastHeader.SignedHeader.Header == nil {
return ""
}
return cs.LastHeader.SignedHeader.Header.ChainID
return cs.ChainID
}
// ClientType is tendermint.
@ -101,12 +105,7 @@ func (cs ClientState) ClientType() clientexported.ClientType {
// GetLatestHeight returns latest block height.
func (cs ClientState) GetLatestHeight() uint64 {
return uint64(cs.LastHeader.Height)
}
// GetLatestTimestamp returns latest block time.
func (cs ClientState) GetLatestTimestamp() time.Time {
return cs.LastHeader.Time
return cs.LatestHeight
}
// IsFrozen returns true if the frozen height has been set.
@ -114,8 +113,17 @@ func (cs ClientState) IsFrozen() bool {
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.
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 {
return err
}
@ -128,6 +136,9 @@ func (cs ClientState) Validate() error {
if cs.MaxClockDrift == 0 {
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 {
return sdkerrors.Wrapf(
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

View File

@ -28,47 +28,52 @@ func (suite *TendermintTestSuite) TestValidate() {
}{
{
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,
},
{
name: "invalid chainID",
clientState: ibctmtypes.NewClientState(" ", lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
expPass: false,
},
{
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,
},
{
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,
},
{
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,
},
{
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,
},
{
name: "invalid header",
clientState: ibctmtypes.NewClientState(lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, ibctmtypes.Header{}, commitmenttypes.GetSDKSpecs()),
name: "invalid height",
clientState: ibctmtypes.NewClientState(chainID, lite.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()),
expPass: false,
},
{
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,
},
{
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,
},
{
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,
},
}
@ -95,7 +100,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
// FIXME: uncomment
// {
// 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{
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
// },
@ -104,7 +109,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
// },
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -113,7 +118,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
},
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -122,7 +127,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -131,7 +136,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
},
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
ValidatorSet: suite.valSet,
@ -173,7 +178,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
// FIXME: uncomment
// {
// name: "successful verification",
// clientState: ibctmtypes.NewClientState(chainID, chainID, height, commitmenttypes.GetSDKSpecs()),
// clientState: ibctmtypes.NewClientState(chainID, chainID, chainID, height, commitmenttypes.GetSDKSpecs()),
// connection: conn,
// consensusState: ibctmtypes.ConsensusState{
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -183,7 +188,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
// },
{
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,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -193,7 +198,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
},
{
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,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -203,7 +208,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
connection: conn,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -213,7 +218,7 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() {
},
{
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,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -266,7 +271,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
// },
{
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,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -276,7 +281,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
},
{
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,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -286,7 +291,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
channel: ch,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -296,7 +301,7 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() {
},
{
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,
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -346,7 +351,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
// },
{
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{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -356,7 +361,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
},
{
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{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -366,7 +371,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
commitment: []byte{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -376,7 +381,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
},
{
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{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -416,7 +421,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
// FIXME: uncomment
// {
// 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,
// consensusState: ibctmtypes.ConsensusState{
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -426,7 +431,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
// },
{
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{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -436,7 +441,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
},
{
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{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -446,7 +451,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
ack: []byte{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -456,7 +461,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
},
{
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{},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
@ -505,7 +510,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
// },
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -514,7 +519,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
},
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -523,7 +528,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -532,7 +537,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() {
},
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
ValidatorSet: suite.valSet,
@ -580,7 +585,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
// },
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -589,7 +594,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
},
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -598,7 +603,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
},
{
name: "client is frozen",
clientState: ibctmtypes.ClientState{LastHeader: suite.header, FrozenHeight: height - 1},
clientState: ibctmtypes.ClientState{LatestHeight: height, FrozenHeight: height - 1},
consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
},
@ -607,7 +612,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
},
{
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{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash),
ValidatorSet: suite.valSet,

View File

@ -3,6 +3,7 @@ package types
import (
"time"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmtypes "github.com/tendermint/tendermint/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@ -13,22 +14,24 @@ import (
// ConsensusState defines a Tendermint consensus state
type ConsensusState struct {
Timestamp time.Time `json:"timestamp" yaml:"timestamp"`
Root commitmentexported.Root `json:"root" yaml:"root"`
Height uint64 `json:"height" yaml:"height"`
ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"`
Timestamp time.Time `json:"timestamp" yaml:"timestamp"`
Root commitmentexported.Root `json:"root" yaml:"root"`
Height uint64 `json:"height" yaml:"height"`
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.
func NewConsensusState(
timestamp time.Time, root commitmentexported.Root, height uint64,
valset *tmtypes.ValidatorSet,
nextValsHash tmbytes.HexBytes, valset *tmtypes.ValidatorSet,
) ConsensusState {
return ConsensusState{
Timestamp: timestamp,
Root: root,
Height: height,
ValidatorSet: valset,
Timestamp: timestamp,
Root: root,
Height: height,
NextValidatorsHash: nextValsHash,
ValidatorSet: valset,
}
}
@ -60,6 +63,9 @@ func (cs ConsensusState) ValidateBasic() error {
if cs.ValidatorSet == 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 {
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "height cannot be 0")
}

View File

@ -10,11 +10,13 @@ const (
// IBC tendermint client sentinel errors
var (
ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 2, "invalid trusting period")
ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 3, "invalid unbonding period")
ErrInvalidHeader = sdkerrors.Register(SubModuleName, 4, "invalid header")
ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 5, "invalid max clock drift")
ErrTrustingPeriodExpired = sdkerrors.Register(SubModuleName, 6, "time since latest trusted state has passed the trusting period")
ErrUnbondingPeriodExpired = sdkerrors.Register(SubModuleName, 7, "time since latest trusted state has passed the unbonding period")
ErrInvalidProofSpecs = sdkerrors.Register(SubModuleName, 8, "invalid proof specs")
ErrInvalidChainID = sdkerrors.Register(SubModuleName, 2, "invalid chain-id")
ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 3, "invalid trusting period")
ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 4, "invalid unbonding period")
ErrInvalidHeaderHeight = sdkerrors.Register(SubModuleName, 5, "invalid header height")
ErrInvalidHeader = sdkerrors.Register(SubModuleName, 6, "invalid header")
ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 7, "invalid max clock drift")
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
root := commitmenttypes.NewMerkleRoot(msg.Header.AppHash)
return ConsensusState{
Timestamp: msg.Header.Time,
Root: root,
Height: uint64(msg.Header.Height),
ValidatorSet: msg.Header.ValidatorSet,
Timestamp: msg.Header.Time,
Root: root,
Height: uint64(msg.Header.Height),
NextValidatorsHash: msg.Header.NextValidatorsHash,
ValidatorSet: msg.Header.ValidatorSet,
}
}

View File

@ -4,6 +4,7 @@ import (
"time"
lite "github.com/tendermint/tendermint/lite2"
tmtypes "github.com/tendermint/tendermint/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
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"
)
// CheckValidityAndUpdateState checks if the provided header is valid and updates
// the consensus state if appropriate. It returns an error if:
// CheckValidityAndUpdateState checks if the provided header is valid, and if valid it will:
// 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 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 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
// in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md).
func CheckValidityAndUpdateState(
clientState clientexported.ClientState, header clientexported.Header,
currentTimestamp time.Time,
clientState clientexported.ClientState, consState clientexported.ConsensusState,
header clientexported.Header, currentTimestamp time.Time,
) (clientexported.ClientState, clientexported.ConsensusState, error) {
tmClientState, ok := clientState.(types.ClientState)
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)
if !ok {
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
}
@ -48,49 +66,58 @@ func CheckValidityAndUpdateState(
}
// checkValidity checks if the Tendermint header is valid.
//
// CONTRACT: assumes header.Height > consensusState.Height
func checkValidity(
clientState types.ClientState, header types.Header, currentTimestamp time.Time,
clientState types.ClientState, consState types.ConsensusState, header types.Header, currentTimestamp time.Time,
) error {
// assert trusting period has not yet passed
if currentTimestamp.Sub(clientState.GetLatestTimestamp()) >= clientState.TrustingPeriod {
if currentTimestamp.Sub(consState.Timestamp) >= clientState.TrustingPeriod {
return sdkerrors.Wrapf(
types.ErrTrustingPeriodExpired,
"current timestamp minus the latest trusted client state timestamp is greater than or equal to the trusting period (%s >= %s)",
currentTimestamp.Sub(clientState.GetLatestTimestamp()), clientState.TrustingPeriod,
"current timestamp minus the consensus state timestamp is greater than or equal to the trusting period (%s >= %s)",
currentTimestamp.Sub(consState.Timestamp), clientState.TrustingPeriod,
)
}
// 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(
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
if header.Time.Unix() <= clientState.GetLatestTimestamp().Unix() {
// assert header timestamp is past latest stored consensus state timestamp
if header.Time.Unix() <= consState.Timestamp.Unix() {
return sdkerrors.Wrapf(
clienttypes.ErrInvalidHeader,
"header blocktime ≤ latest client state block time (%s ≤ %s)",
header.Time.UTC(), clientState.GetLatestTimestamp().UTC(),
"header timestamp ≤ consensus state timestamp (%s ≤ %s)",
header.Time.UTC(), consState.Timestamp.UTC(),
)
}
// assert header height is newer than any we know
if header.GetHeight() <= clientState.GetLatestHeight() {
// assert header height is newer than consensus state
if header.GetHeight() <= consState.Height {
return sdkerrors.Wrapf(
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
err := lite.Verify(
clientState.GetChainID(), &clientState.LastHeader.SignedHeader,
clientState.LastHeader.ValidatorSet, &header.SignedHeader, header.ValidatorSet,
clientState.GetChainID(), &signedHeader,
consState.ValidatorSet, &header.SignedHeader, header.ValidatorSet,
clientState.TrustingPeriod, currentTimestamp, clientState.MaxClockDrift, clientState.TrustLevel,
)
if err != nil {
@ -101,12 +128,15 @@ func checkValidity(
// update the consensus state from a new header
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{
Height: uint64(header.Height),
Timestamp: header.Time,
Root: commitmenttypes.NewMerkleRoot(header.AppHash),
ValidatorSet: header.ValidatorSet,
Height: uint64(header.Height),
Timestamp: header.Time,
Root: commitmenttypes.NewMerkleRoot(header.AppHash),
NextValidatorsHash: header.NextValidatorsHash,
ValidatorSet: header.ValidatorSet,
}
return clientState, consensusState

View File

@ -14,9 +14,10 @@ import (
func (suite *TendermintTestSuite) TestCheckValidity() {
var (
clientState ibctmtypes.ClientState
newHeader ibctmtypes.Header
currentTime time.Time
clientState ibctmtypes.ClientState
consensusState ibctmtypes.ConsensusState
newHeader ibctmtypes.Header
currentTime time.Time
)
// 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",
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)
currentTime = suite.now
},
@ -63,25 +65,58 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
{
name: "successful update with future height and different validator set",
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)
currentTime = suite.now
},
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",
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)
currentTime = suite.now
},
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",
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)
currentTime = suite.now
},
@ -90,17 +125,19 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
{
name: "unsuccessful update: trusting period has passed since last client timestamp",
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)
// make current time pass trusting period from last timestamp on clientstate
currentTime = suite.now.Add(ubdPeriod)
currentTime = suite.now.Add(trustingPeriod)
},
expPass: false,
},
{
name: "unsuccessful update: header timestamp is past current timestamp",
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)
currentTime = suite.now
},
@ -109,7 +146,8 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
{
name: "unsuccessful update: header timestamp is not past last client timestamp",
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)
currentTime = suite.now
},
@ -118,7 +156,8 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
{
name: "header basic validation failed",
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)
// cause new header to fail validatebasic by changing commit height to mismatch header height
newHeader.SignedHeader.Commit.Height = height - 1
@ -127,14 +166,14 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
expPass: false,
},
{
name: "header height < latest client height",
name: "header height < consensus height",
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
newHeader = ibctmtypes.CreateTestHeader(chainID, height-1, suite.headerTime, suite.valSet, signers)
currentTime = suite.now
},
expPass: false,
},
}
@ -145,21 +184,31 @@ func (suite *TendermintTestSuite) TestCheckValidity() {
tc.setup()
expectedConsensus := ibctmtypes.ConsensusState{
Height: uint64(newHeader.Height),
Timestamp: newHeader.Time,
Root: commitmenttypes.NewMerkleRoot(newHeader.AppHash),
ValidatorSet: newHeader.ValidatorSet,
Height: uint64(newHeader.Height),
Timestamp: newHeader.Time,
Root: commitmenttypes.NewMerkleRoot(newHeader.AppHash),
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 {
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)
} else {
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)
}
}

View File

@ -51,6 +51,11 @@ func (cs ClientState) IsFrozen() bool {
return false
}
// GetFrozenHeight returns 0.
func (cs ClientState) GetFrozenHeight() uint64 {
return 0
}
// Validate performs a basic validation of the client state fields.
func (cs ClientState) Validate() error {
if strings.TrimSpace(cs.ChainID) == "" {

View File

@ -32,7 +32,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
ClientGenesis: clienttypes.NewGenesisState(
[]clienttypes.GenesisClientState{
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(
exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10),
@ -43,7 +43,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
clientID,
[]exported.ConsensusState{
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(
[]clienttypes.GenesisClientState{
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(
exported.ClientTypeLocalHost, localhosttypes.NewClientState("(chaindID)", 0),

View File

@ -17,6 +17,8 @@ import (
)
const (
chainID = "chainID"
connectionID = "connectionidone"
clientID = "clientidone"
connectionID2 = "connectionidtwo"
@ -31,6 +33,8 @@ const (
channelOrder = channeltypes.ORDERED
channelVersion = "1.0"
height = 10
trustingPeriod time.Duration = time.Hour * 24 * 7 * 2
ubdPeriod time.Duration = time.Hour * 24 * 7 * 3
maxClockDrift time.Duration = time.Second * 10
@ -58,7 +62,7 @@ func (suite *IBCTestSuite) SetupTest() {
val := tmtypes.NewValidator(pubKey, 10)
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.ctx = suite.app.BaseApp.NewContext(isCheckTx, abci.Header{})

View File

@ -202,7 +202,9 @@ func (chain *TestChain) NextBlock() {
AppHash: chain.App.LastCommitID().Hash,
// NOTE: the time is increased by the coordinator to maintain time synchrony amongst
// 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})