Migrate IBC tendermint header to proto (#7120)

* gen header proto file

* fix tm type to proto conversion issues

* fix tendermint type tests

* fix remaining tests

* fix lint

* Update x/ibc/07-tendermint/types/header.go

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Update x/ibc/07-tendermint/types/header.go

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* apply @fedekunze review suggestions

* fix build

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
colin axnér 2020-08-20 17:46:11 +02:00 committed by GitHub
parent 3368dae5f5
commit be0cc63808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 759 additions and 202 deletions

View File

@ -371,6 +371,7 @@ proto-update-deps:
@curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto @curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto
@curl -sSL $(TM_URL)/types/evidence.proto > $(TM_TYPES)/evidence.proto @curl -sSL $(TM_URL)/types/evidence.proto > $(TM_TYPES)/evidence.proto
@curl -sSL $(TM_URL)/types/params.proto > $(TM_TYPES)/params.proto @curl -sSL $(TM_URL)/types/params.proto > $(TM_TYPES)/params.proto
@curl -sSL $(TM_URL)/types/validator.proto > $(TM_TYPES)/validator.proto
@mkdir -p $(TM_CRYPTO_TYPES) @mkdir -p $(TM_CRYPTO_TYPES)
@curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto @curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto

View File

@ -3,6 +3,8 @@ package ibc.tendermint;
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"; option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types";
import "tendermint/types/validator.proto";
import "tendermint/types/types.proto";
import "confio/proofs.proto"; import "confio/proofs.proto";
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
@ -14,7 +16,7 @@ import "gogoproto/gogo.proto";
message ClientState { message ClientState {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
string chain_id = 1; string chain_id = 1;
Fraction trust_level = 2 [ Fraction trust_level = 2 [
(gogoproto.nullable) = false, (gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"trust_level\"" (gogoproto.moretags) = "yaml:\"trust_level\""
@ -22,21 +24,21 @@ message ClientState {
// duration of the period since the LastestTimestamp during which the // duration of the period since the LastestTimestamp during which the
// submitted headers are valid for upgrade // submitted headers are valid for upgrade
google.protobuf.Duration trusting_period = 3 [ google.protobuf.Duration trusting_period = 3 [
(gogoproto.nullable) = false, (gogoproto.nullable) = false,
(gogoproto.stdduration) = true, (gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"trusting_period\"" (gogoproto.moretags) = "yaml:\"trusting_period\""
]; ];
// duration of the staking unbonding period // duration of the staking unbonding period
google.protobuf.Duration unbonding_period = 4 [ google.protobuf.Duration unbonding_period = 4 [
(gogoproto.nullable) = false, (gogoproto.nullable) = false,
(gogoproto.stdduration) = true, (gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"unbonding_period\"" (gogoproto.moretags) = "yaml:\"unbonding_period\""
]; ];
// defines how much new (untrusted) header's Time can drift into the future. // defines how much new (untrusted) header's Time can drift into the future.
google.protobuf.Duration max_clock_drift = 5 [ google.protobuf.Duration max_clock_drift = 5 [
(gogoproto.nullable) = false, (gogoproto.nullable) = false,
(gogoproto.stdduration) = true, (gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"max_clock_drift\"" (gogoproto.moretags) = "yaml:\"max_clock_drift\""
]; ];
// Block height when the client was frozen due to a misbehaviour // Block height when the client was frozen due to a misbehaviour
uint64 frozen_height = 6 [(gogoproto.moretags) = "yaml:\"frozen_height\""]; uint64 frozen_height = 6 [(gogoproto.moretags) = "yaml:\"frozen_height\""];
@ -58,15 +60,42 @@ message ConsensusState {
// commitment root (i.e app hash) // commitment root (i.e app hash)
ibc.commitment.MerkleRoot root = 2 [(gogoproto.nullable) = false]; ibc.commitment.MerkleRoot root = 2 [(gogoproto.nullable) = false];
// height at which the consensus state was stored. // height at which the consensus state was stored.
uint64 height = 3; uint64 height = 3;
bytes next_validators_hash = 4 [ bytes next_validators_hash = 4 [
(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes", (gogoproto.casttype) =
"github.com/tendermint/tendermint/libs/bytes.HexBytes",
(gogoproto.moretags) = "yaml:\"next_validators_hash\"" (gogoproto.moretags) = "yaml:\"next_validators_hash\""
]; ];
} }
// Header defines the Tendermint client consensus Header.
// It encapsulates all the information necessary to update from a trusted
// Tendermint ConsensusState. The inclusion of TrustedHeight and
// TrustedValidators allows this update to process correctly, so long as the
// ConsensusState for the TrustedHeight exists, this removes race conditions
// among relayers The SignedHeader and ValidatorSet are the new untrusted update
// fields for the client. The TrustedHeight is the height of a stored
// ConsensusState on the client that will be used to verify the new untrusted
// header. The Trusted ConsensusState must be within the unbonding period of
// current time in order to correctly verify, and the TrustedValidators must
// hash to TrustedConsensusState.NextValidatorsHash since that is the last
// trusted validator set at the TrustedHeight.
message Header {
.tendermint.types.SignedHeader signed_header = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"signed_header\""
];
.tendermint.types.ValidatorSet validator_set = 2
[(gogoproto.moretags) = "yaml:\"validator_set\""];
uint64 trusted_height = 3 [(gogoproto.moretags) = "yaml:\"trusted_height\""];
.tendermint.types.ValidatorSet trusted_validators = 4
[(gogoproto.moretags) = "yaml:\"trusted_validators\""];
}
// Fraction defines the protobuf message type for tmmath.Fraction // Fraction defines the protobuf message type for tmmath.Fraction
message Fraction { message Fraction {
int64 numerator = 1; int64 numerator = 1;
int64 denominator = 2; int64 denominator = 2;
} }

View File

@ -0,0 +1,25 @@
syntax = "proto3";
package tendermint.types;
option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
import "gogoproto/gogo.proto";
import "tendermint/crypto/keys.proto";
message ValidatorSet {
repeated Validator validators = 1;
Validator proposer = 2;
int64 total_voting_power = 3;
}
message Validator {
bytes address = 1;
tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false];
int64 voting_power = 3;
int64 proposer_priority = 4;
}
message SimpleValidator {
tendermint.crypto.PublicKey pub_key = 1;
int64 voting_power = 2;
}

View File

@ -148,9 +148,15 @@ func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64,
return ibctmtypes.Header{}, 0, err return ibctmtypes.Header{}, 0, err
} }
protoCommit := commit.SignedHeader.ToProto()
protoValset, err := tmtypes.NewValidatorSet(validators.Validators).ToProto()
if err != nil {
return ibctmtypes.Header{}, 0, err
}
header := ibctmtypes.Header{ header := ibctmtypes.Header{
SignedHeader: commit.SignedHeader, SignedHeader: *protoCommit,
ValidatorSet: tmtypes.NewValidatorSet(validators.Validators), ValidatorSet: protoValset,
} }
return header, height, nil return header, height, nil

View File

@ -57,11 +57,11 @@ 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
createFutureUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header { createFutureUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
return ibctmtypes.CreateTestHeader(testChainID, suite.header.Height+3, suite.header.Height, suite.header.Time.Add(time.Hour), return ibctmtypes.CreateTestHeader(testChainID, int64(suite.header.GetHeight()+3), int64(suite.header.GetHeight()), suite.header.Header.Time.Add(time.Hour),
suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal})
} }
createPastUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header { createPastUpdateFn := func(s *KeeperTestSuite) ibctmtypes.Header {
return ibctmtypes.CreateTestHeader(testChainID, suite.header.Height-2, suite.header.Height-4, suite.header.Time, return ibctmtypes.CreateTestHeader(testChainID, int64(suite.header.GetHeight()-2), int64(suite.header.GetHeight())-4, suite.header.Header.Time,
suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal})
} }
var ( var (
@ -189,7 +189,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
err := tc.malleate() err := tc.malleate()
suite.Require().NoError(err) suite.Require().NoError(err)
suite.ctx = suite.ctx.WithBlockTime(updateHeader.Time.Add(time.Minute)) suite.ctx = suite.ctx.WithBlockTime(updateHeader.Header.Time.Add(time.Minute))
updatedClientState, err := suite.keeper.UpdateClient(suite.ctx, testClientID, updateHeader) updatedClientState, err := suite.keeper.UpdateClient(suite.ctx, testClientID, updateHeader)
@ -198,9 +198,9 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
expConsensusState := &ibctmtypes.ConsensusState{ expConsensusState := &ibctmtypes.ConsensusState{
Height: updateHeader.GetHeight(), Height: updateHeader.GetHeight(),
Timestamp: updateHeader.Time, Timestamp: updateHeader.GetTime(),
Root: commitmenttypes.NewMerkleRoot(updateHeader.AppHash), Root: commitmenttypes.NewMerkleRoot(updateHeader.Header.GetAppHash()),
NextValidatorsHash: updateHeader.NextValidatorsHash, NextValidatorsHash: updateHeader.Header.NextValidatorsHash,
} }
newClientState, found := suite.keeper.GetClientState(suite.ctx, testClientID) newClientState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
@ -212,9 +212,9 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
suite.Require().Equal(updatedClientState, newClientState, "updatedClient state not persisted correctly") suite.Require().Equal(updatedClientState, newClientState, "updatedClient state not persisted correctly")
// Determine if clientState should be updated or not // Determine if clientState should be updated or not
if uint64(updateHeader.Height) > clientState.GetLatestHeight() { if uint64(updateHeader.GetHeight()) > clientState.GetLatestHeight() {
// Header Height is greater than clientState latest Height, clientState should be updated with header.Height // Header Height is greater than clientState latest Height, clientState should be updated with header.GetHeight()
suite.Require().Equal(uint64(updateHeader.Height), updatedClientState.GetLatestHeight(), "clientstate height did not update") suite.Require().Equal(uint64(updateHeader.GetHeight()), updatedClientState.GetLatestHeight(), "clientstate height did not update")
} else { } else {
// Update will add past consensus state, clientState should not be updated at all // 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().Equal(clientState.GetLatestHeight(), updatedClientState.GetLatestHeight(), "client state height updated for past header")

View File

@ -191,7 +191,7 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported.
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.GetAppHash()),
NextValidatorsHash: histInfo.Header.NextValidatorsHash, NextValidatorsHash: histInfo.Header.NextValidatorsHash,
} }
return consensusState, true return consensusState, true

View File

@ -212,11 +212,11 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() {
nextState := ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("next")), testClientHeight+5, suite.valSetHash) nextState := ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("next")), testClientHeight+5, suite.valSetHash)
header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, testClientHeight, suite.header.Time.Add(time.Minute), header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, testClientHeight, suite.header.Header.Time.Add(time.Minute),
suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal})
// mock update functionality // mock update functionality
clientState.LatestHeight = uint64(header.Height) clientState.LatestHeight = header.GetHeight()
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)

View File

@ -60,7 +60,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.NextValidatorsHash, header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.GetHeight(), header.Header.NextValidatorsHash,
), ),
}, },
), ),
@ -85,7 +85,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.NextValidatorsHash, header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.GetHeight(), header.Header.NextValidatorsHash,
), ),
}, },
), ),
@ -124,7 +124,7 @@ func TestValidateGenesis(t *testing.T) {
"(CLIENTID2)", "(CLIENTID2)",
[]exported.ConsensusState{ []exported.ConsensusState{
ibctmtypes.NewConsensusState( ibctmtypes.NewConsensusState(
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.NextValidatorsHash, header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), 0, header.Header.NextValidatorsHash,
), ),
}, },
), ),
@ -149,7 +149,7 @@ func TestValidateGenesis(t *testing.T) {
clientID, clientID,
[]exported.ConsensusState{ []exported.ConsensusState{
ibctmtypes.NewConsensusState( ibctmtypes.NewConsensusState(
header.Time, commitmenttypes.NewMerkleRoot(header.AppHash), 0, header.NextValidatorsHash, header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), 0, header.Header.NextValidatorsHash,
), ),
}, },
), ),

View File

@ -118,12 +118,12 @@ func (suite *KeeperTestSuite) TestGetTimestampAtHeight() {
tc.malleate() tc.malleate()
actualTimestamp, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetTimestampAtHeight( actualTimestamp, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetTimestampAtHeight(
suite.chainA.GetContext(), connection, uint64(suite.chainB.LastHeader.Height), suite.chainA.GetContext(), connection, uint64(suite.chainB.LastHeader.GetHeight()),
) )
if tc.expPass { if tc.expPass {
suite.Require().NoError(err) suite.Require().NoError(err)
suite.Require().EqualValues(uint64(suite.chainB.LastHeader.Time.UnixNano()), actualTimestamp) suite.Require().EqualValues(uint64(suite.chainB.LastHeader.GetTime().UnixNano()), actualTimestamp)
} else { } else {
suite.Require().Error(err) suite.Require().Error(err)
} }

View File

@ -106,7 +106,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
// name: "successful verification", // name: "successful verification",
// clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), // clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
// consensusState: ibctmtypes.ConsensusState{ // consensusState: ibctmtypes.ConsensusState{
// Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), // Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
// }, // },
// prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")),
// expPass: true, // expPass: true,
@ -115,7 +115,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
name: "ApplyPrefix failed", name: "ApplyPrefix failed",
clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
consensusState: ibctmtypes.ConsensusState{ consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
}, },
prefix: commitmenttypes.MerklePrefix{}, prefix: commitmenttypes.MerklePrefix{},
expPass: false, expPass: false,
@ -124,7 +124,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
name: "latest client height < height", name: "latest client height < height",
clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
consensusState: ibctmtypes.ConsensusState{ consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
}, },
prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")),
expPass: false, expPass: false,
@ -133,7 +133,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
name: "client is frozen", name: "client is frozen",
clientState: &ibctmtypes.ClientState{LatestHeight: height, 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.Header.GetAppHash()),
}, },
prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")),
expPass: false, expPass: false,
@ -142,7 +142,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
name: "proof verification failed", name: "proof verification failed",
clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), clientState: ibctmtypes.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()),
consensusState: ibctmtypes.ConsensusState{ consensusState: ibctmtypes.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.AppHash), Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
NextValidatorsHash: suite.valsHash, NextValidatorsHash: suite.valsHash,
}, },
prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")),

View File

@ -8,6 +8,7 @@ import (
"github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/crypto/tmhash"
tmbytes "github.com/tendermint/tendermint/libs/bytes" tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
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"
@ -72,14 +73,14 @@ func (ev Evidence) Hash() tmbytes.HexBytes {
// //
// NOTE: assumes that evidence headers have the same height // NOTE: assumes that evidence headers have the same height
func (ev Evidence) GetHeight() int64 { func (ev Evidence) GetHeight() int64 {
return int64(math.Min(float64(ev.Header1.Height), float64(ev.Header2.Height))) return int64(math.Min(float64(ev.Header1.GetHeight()), float64(ev.Header2.GetHeight())))
} }
// GetTime returns the timestamp at which misbehaviour occurred. It uses the // GetTime returns the timestamp at which misbehaviour occurred. It uses the
// maximum value from both headers to prevent producing an invalid header outside // maximum value from both headers to prevent producing an invalid header outside
// of the evidence age range. // of the evidence age range.
func (ev Evidence) GetTime() time.Time { func (ev Evidence) GetTime() time.Time {
minTime := int64(math.Max(float64(ev.Header1.Time.UnixNano()), float64(ev.Header2.Time.UnixNano()))) minTime := int64(math.Max(float64(ev.Header1.GetTime().UnixNano()), float64(ev.Header2.GetTime().UnixNano())))
return time.Unix(0, minTime) return time.Unix(0, minTime)
} }
@ -116,12 +117,22 @@ func (ev Evidence) ValidateBasic() error {
) )
} }
// Ensure that Heights are the same // Ensure that Heights are the same
if ev.Header1.Height != ev.Header2.Height { if ev.Header1.GetHeight() != ev.Header2.GetHeight() {
return sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "headers in evidence are on different heights (%d ≠ %d)", ev.Header1.Height, ev.Header2.Height) return sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "headers in evidence are on different heights (%d ≠ %d)", ev.Header1.GetHeight(), ev.Header2.GetHeight())
} }
blockID1, err := tmtypes.BlockIDFromProto(&ev.Header1.SignedHeader.Commit.BlockID)
if err != nil {
return sdkerrors.Wrap(err, "invalid block ID from header 1 in evidence")
}
blockID2, err := tmtypes.BlockIDFromProto(&ev.Header2.SignedHeader.Commit.BlockID)
if err != nil {
return sdkerrors.Wrap(err, "invalid block ID from header 2 in evidence")
}
// Ensure that Commit Hashes are different // Ensure that Commit Hashes are different
if ev.Header1.Commit.BlockID.Equals(ev.Header2.Commit.BlockID) { if blockID1.Equals(*blockID2) {
return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, "headers commit to same blockID") return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, "headers blockIDs are not equal")
} }
if err := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err != nil { if err := ValidCommit(ev.ChainID, ev.Header1.Commit, ev.Header1.ValidatorSet); err != nil {
return err return err
@ -137,21 +148,30 @@ func (ev Evidence) ValidateBasic() error {
// CommitToVoteSet will panic if the commit cannot be converted to a valid voteset given the validatorset // CommitToVoteSet will panic if the commit cannot be converted to a valid voteset given the validatorset
// This implies that someone tried to submit evidence that wasn't actually committed by the validatorset // This implies that someone tried to submit evidence that wasn't actually committed by the validatorset
// thus we should return an error here and reject the evidence rather than panicing. // thus we should return an error here and reject the evidence rather than panicing.
func ValidCommit(chainID string, commit *tmtypes.Commit, valSet *tmtypes.ValidatorSet) (err error) { func ValidCommit(chainID string, commit *tmproto.Commit, valSet *tmproto.ValidatorSet) (err error) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
err = sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "invalid commit: %v", r) err = sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "invalid commit: %v", r)
} }
}() }()
tmCommit, err := tmtypes.CommitFromProto(commit)
if err != nil {
return sdkerrors.Wrap(err, "commit is not tendermint commit type")
}
tmValset, err := tmtypes.ValidatorSetFromProto(valSet)
if err != nil {
return sdkerrors.Wrap(err, "validator set is not tendermint validator set type")
}
// Convert commits to vote-sets given the validator set so we can check if they both have 2/3 power // Convert commits to vote-sets given the validator set so we can check if they both have 2/3 power
voteSet := tmtypes.CommitToVoteSet(chainID, commit, valSet) voteSet := tmtypes.CommitToVoteSet(chainID, tmCommit, tmValset)
blockID, ok := voteSet.TwoThirdsMajority() blockID, ok := voteSet.TwoThirdsMajority()
// Check that ValidatorSet did indeed commit to blockID in Commit // Check that ValidatorSet did indeed commit to blockID in Commit
if !ok || !blockID.Equals(commit.BlockID) { if !ok || !blockID.Equals(tmCommit.BlockID) {
return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, "validator set did not commit to header 1") return sdkerrors.Wrap(clienttypes.ErrInvalidEvidence, "validator set did not commit to header")
} }
return nil return nil

View File

@ -4,7 +4,6 @@ import (
"time" "time"
"github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/crypto/tmhash"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -27,7 +26,8 @@ func (suite *TendermintTestSuite) TestEvidence() {
suite.Require().Equal(ev.GetClientID(), clientID) suite.Require().Equal(ev.GetClientID(), clientID)
suite.Require().Equal(ev.Route(), "client") suite.Require().Equal(ev.Route(), "client")
suite.Require().Equal(ev.Type(), "client_misbehaviour") suite.Require().Equal(ev.Type(), "client_misbehaviour")
suite.Require().Equal(ev.Hash(), tmbytes.HexBytes(tmhash.Sum(suite.aminoCdc.MustMarshalBinaryBare(ev)))) // uncomment when evidence is migrated to proto
// suite.Require().Equal(ev.Hash(), tmbytes.HexBytes(tmhash.Sum(suite.aminoCdc.MustMarshalBinaryBare(ev))))
suite.Require().Equal(ev.GetHeight(), int64(height)) suite.Require().Equal(ev.GetHeight(), int64(height))
} }
@ -188,9 +188,14 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() {
}, },
func(ev *ibctmtypes.Evidence) error { func(ev *ibctmtypes.Evidence) error {
// voteSet contains only altVal which is less than 2/3 of total power (height/1height) // voteSet contains only altVal which is less than 2/3 of total power (height/1height)
wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header1.Height, 1, tmproto.PrecommitType, altValSet) wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(ev.Header1.GetHeight()), 1, tmproto.PrecommitType, altValSet)
var err error blockID, err := tmtypes.BlockIDFromProto(&ev.Header1.Commit.BlockID)
ev.Header1.Commit, err = tmtypes.MakeCommit(ev.Header1.Commit.BlockID, ev.Header2.Height, ev.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now) if err != nil {
return err
}
tmCommit, err := tmtypes.MakeCommit(*blockID, int64(ev.Header2.GetHeight()), ev.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now)
ev.Header1.Commit = tmCommit.ToProto()
return err return err
}, },
false, false,
@ -205,9 +210,14 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() {
}, },
func(ev *ibctmtypes.Evidence) error { func(ev *ibctmtypes.Evidence) error {
// voteSet contains only altVal which is less than 2/3 of total power (height/1height) // voteSet contains only altVal which is less than 2/3 of total power (height/1height)
wrongVoteSet := tmtypes.NewVoteSet(chainID, ev.Header2.Height, 1, tmproto.PrecommitType, altValSet) wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(ev.Header2.GetHeight()), 1, tmproto.PrecommitType, altValSet)
var err error blockID, err := tmtypes.BlockIDFromProto(&ev.Header2.Commit.BlockID)
ev.Header2.Commit, err = tmtypes.MakeCommit(ev.Header2.Commit.BlockID, ev.Header2.Height, ev.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now) if err != nil {
return err
}
tmCommit, err := tmtypes.MakeCommit(*blockID, int64(ev.Header2.GetHeight()), ev.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now)
ev.Header2.Commit = tmCommit.ToProto()
return err return err
}, },
false, false,
@ -221,7 +231,8 @@ func (suite *TendermintTestSuite) TestEvidenceValidateBasic() {
ClientID: clientID, ClientID: clientID,
}, },
func(ev *ibctmtypes.Evidence) error { func(ev *ibctmtypes.Evidence) error {
ev.Header2.Commit.BlockID = ibctmtypes.MakeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) tmBlockID := ibctmtypes.MakeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset")))
ev.Header2.Commit.BlockID = tmBlockID.ToProto()
return nil return nil
}, },
false, false,

View File

@ -2,6 +2,7 @@ package types
import ( import (
"bytes" "bytes"
"time"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -13,22 +14,6 @@ import (
var _ clientexported.Header = Header{} var _ clientexported.Header = Header{}
// Header defines the Tendermint client consensus Header.
// It encapsulates all the information necessary to update from a trusted Tendermint ConsensusState.
// The inclusion of TrustedHeight and TrustedValidators allows this update to process correctly, so long
// as the ConsensusState for the TrustedHeight exists, this removes race conditions among relayers
// The SignedHeader and ValidatorSet are the new untrusted update fields for the client.
// The TrustedHeight is the height of a stored ConsensusState on the client that will be used to verify the new untrusted header.
// The Trusted ConsensusState must be within the unbonding period of current time in order to correctly verify,
// and the TrustedValidators must hash to TrustedConsensusState.NextValidatorsHash since that is the last trusted validator set
// at the TrustedHeight.
type Header struct {
tmtypes.SignedHeader `json:"signed_header" yaml:"signed_header"` // contains the commitment root
ValidatorSet *tmtypes.ValidatorSet `json:"validator_set" yaml:"validator_set"` // the validator set that signed Header
TrustedHeight uint64 `json:"trusted_height" yaml:"trusted_height"` // the height of a trusted header seen by client less than or equal to Header
TrustedValidators *tmtypes.ValidatorSet `json:"trusted_vals" yaml:"trusted_vals"` // the last trusted validator set at trusted height
}
// ClientType defines that the Header is a Tendermint consensus algorithm // ClientType defines that the Header is a Tendermint consensus algorithm
func (h Header) ClientType() clientexported.ClientType { func (h Header) ClientType() clientexported.ClientType {
return clientexported.Tendermint return clientexported.Tendermint
@ -37,38 +22,65 @@ func (h Header) ClientType() clientexported.ClientType {
// ConsensusState returns the updated consensus state associated with the header // ConsensusState returns the updated consensus state associated with the header
func (h Header) ConsensusState() *ConsensusState { func (h Header) ConsensusState() *ConsensusState {
return &ConsensusState{ return &ConsensusState{
Height: uint64(h.Height), Height: h.GetHeight(),
Timestamp: h.Time, Timestamp: h.GetTime(),
Root: commitmenttypes.NewMerkleRoot(h.AppHash), Root: commitmenttypes.NewMerkleRoot(h.Header.GetAppHash()),
NextValidatorsHash: h.NextValidatorsHash, NextValidatorsHash: h.Header.NextValidatorsHash,
} }
} }
// GetHeight returns the current height // GetHeight returns the current height. It returns 0 if the tendermint
// header is nil.
// //
// NOTE: also referred as `sequence` // NOTE: also referred as `sequence`
func (h Header) GetHeight() uint64 { func (h Header) GetHeight() uint64 {
return uint64(h.Height) if h.Header == nil {
return 0
}
return uint64(h.Header.Height)
} }
// ValidateBasic calls the SignedHeader ValidateBasic function // GetTime returns the current block timestamp. It returns a zero time if
// and checks that validatorsets are not nil // the tendermint header is nil.
func (h Header) GetTime() time.Time {
if h.Header == nil {
return time.Time{}
}
return h.Header.Time
}
// ValidateBasic calls the SignedHeader ValidateBasic function and checks
// that validatorsets are not nil.
// NOTE: TrustedHeight and TrustedValidators may be empty when creating client // NOTE: TrustedHeight and TrustedValidators may be empty when creating client
// with MsgCreateClient // with MsgCreateClient
func (h Header) ValidateBasic(chainID string) error { func (h Header) ValidateBasic(chainID string) error {
if err := h.SignedHeader.ValidateBasic(chainID); err != nil { if h.Header == nil {
return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "tendermint header cannot be nil")
}
tmSignedHeader, err := tmtypes.SignedHeaderFromProto(&h.SignedHeader)
if err != nil {
return sdkerrors.Wrap(err, "header is not a tendermint header")
}
if err := tmSignedHeader.ValidateBasic(chainID); err != nil {
return sdkerrors.Wrap(err, "header failed basic validation") return sdkerrors.Wrap(err, "header failed basic validation")
} }
// TrustedHeight is less than Header for updates // TrustedHeight is less than Header for updates
// and less than or equal to Header for misbehaviour // and less than or equal to Header for misbehaviour
if h.TrustedHeight > uint64(h.Height) { if h.TrustedHeight > h.GetHeight() {
return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "TrustedHeight %d must be less than or equal to header height %d", return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "TrustedHeight %d must be less than or equal to header height %d",
h.TrustedHeight, h.Height) h.TrustedHeight, h.GetHeight())
} }
if h.ValidatorSet == nil { if h.ValidatorSet == nil {
return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil") return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil")
} }
if !bytes.Equal(h.ValidatorsHash, h.ValidatorSet.Hash()) { tmValset, err := tmtypes.ValidatorSetFromProto(h.ValidatorSet)
if err != nil {
return sdkerrors.Wrap(err, "validator set is not tendermint validator set")
}
if !bytes.Equal(h.Header.ValidatorsHash, tmValset.Hash()) {
return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set does not match hash") return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set does not match hash")
} }
return nil return nil

View File

@ -1,30 +1,76 @@
package types_test package types_test
import ( import (
"time"
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
) )
func (suite *TendermintTestSuite) TestGetHeight() {
header := suite.chainA.LastHeader
suite.Require().NotEqual(uint64(0), header.GetHeight())
header.Header = nil
suite.Require().Equal(uint64(0), header.GetHeight())
}
func (suite *TendermintTestSuite) TestGetTime() {
header := suite.chainA.LastHeader
suite.Require().NotEqual(time.Time{}, header.GetTime())
header.Header = nil
suite.Require().Equal(time.Time{}, header.GetTime())
}
func (suite *TendermintTestSuite) TestHeaderValidateBasic() { func (suite *TendermintTestSuite) TestHeaderValidateBasic() {
testCases := []struct { var (
name string header types.Header
header ibctmtypes.Header
chainID string chainID string
expPass bool )
testCases := []struct {
name string
malleate func()
expPass bool
}{ }{
{"valid header", suite.header, chainID, true}, {"valid header", func() {}, true},
{"signed header basic validation failed", suite.header, "chainID", false}, {"signed header is nil", func() {
{"validator set nil", ibctmtypes.Header{suite.header.SignedHeader, nil, 0, suite.valSet}, chainID, false}, header.Header = nil
}, false},
{"signed header failed tendermint ValidateBasic", func() {
header = suite.chainA.LastHeader
chainID = "chainid"
}, false},
{"trusted height is greater than header height", func() {
header.TrustedHeight = header.GetHeight() + 1
}, false},
{"validator set nil", func() {
header.ValidatorSet = nil
}, false},
{"header validator hash does not equal hash of validator set", func() {
// use chainB's randomly generated validator set
header.ValidatorSet = suite.chainB.LastHeader.ValidatorSet
}, false},
} }
suite.Require().Equal(clientexported.Tendermint, suite.header.ClientType()) suite.Require().Equal(clientexported.Tendermint, suite.header.ClientType())
for i, tc := range testCases { for _, tc := range testCases {
tc := tc tc := tc
if tc.expPass {
suite.Require().NoError(tc.header.ValidateBasic(tc.chainID), "valid test case %d failed: %s", i, tc.name) suite.Run(tc.name, func() {
} else { chainID = suite.chainA.ChainID // must be explicitly changed in malleate
suite.Require().Error(tc.header.ValidateBasic(tc.chainID), "invalid test case %d passed: %s", i, tc.name) header = suite.chainA.LastHeader // must be explicitly changed in malleate
}
tc.malleate()
err := header.ValidateBasic(chainID)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
} }
} }

View File

@ -3,6 +3,8 @@ package types
import ( import (
"time" "time"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@ -103,6 +105,17 @@ func (cs ClientState) CheckMisbehaviourAndUpdateState(
func checkMisbehaviourHeader( func checkMisbehaviourHeader(
clientState *ClientState, consState *ConsensusState, header Header, currentTimestamp time.Time, clientState *ClientState, consState *ConsensusState, header Header, currentTimestamp time.Time,
) error { ) error {
tmTrustedValset, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators)
if err != nil {
return sdkerrors.Wrap(err, "trusted validator set is not tendermint validator set type")
}
tmCommit, err := tmtypes.CommitFromProto(header.Commit)
if err != nil {
return sdkerrors.Wrap(err, "commit is not tendermint commit type")
}
// check the trusted fields for the header against ConsensusState // check the trusted fields for the header against ConsensusState
if err := checkTrustedHeader(header, consState); err != nil { if err := checkTrustedHeader(header, consState); err != nil {
return err return err
@ -119,8 +132,8 @@ func checkMisbehaviourHeader(
// - ValidatorSet must have 2/3 similarity with trusted FromValidatorSet // - ValidatorSet must have 2/3 similarity with trusted FromValidatorSet
// - ValidatorSets on both headers are valid given the last trusted ValidatorSet // - ValidatorSets on both headers are valid given the last trusted ValidatorSet
if err := header.TrustedValidators.VerifyCommitLightTrusting( if err := tmTrustedValset.VerifyCommitLightTrusting(
clientState.GetChainID(), header.Commit, clientState.TrustLevel.ToTendermint(), clientState.GetChainID(), tmCommit, clientState.TrustLevel.ToTendermint(),
); err != nil { ); err != nil {
return sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "validator set in header has too much change from trusted validator set: %v", err) return sdkerrors.Wrapf(clienttypes.ErrInvalidEvidence, "validator set in header has too much change from trusted validator set: %v", err)
} }

View File

@ -95,7 +95,7 @@ func (msg MsgCreateClient) ValidateBasic() error {
return sdkerrors.Wrap(ErrInvalidHeader, "header cannot be nil") return sdkerrors.Wrap(ErrInvalidHeader, "header cannot be nil")
} }
// ValidateBasic of provided header with self-attested chain-id // ValidateBasic of provided header with self-attested chain-id
if err := msg.Header.ValidateBasic(msg.Header.ChainID); err != nil { if err := msg.Header.ValidateBasic(msg.Header.Header.GetChainID()); err != nil {
return sdkerrors.Wrapf(ErrInvalidHeader, "header failed validatebasic with its own chain-id: %v", err) return sdkerrors.Wrapf(ErrInvalidHeader, "header failed validatebasic with its own chain-id: %v", err)
} }
if msg.TrustingPeriod >= msg.UnbondingPeriod { if msg.TrustingPeriod >= msg.UnbondingPeriod {
@ -139,20 +139,20 @@ func (msg MsgCreateClient) GetClientType() string {
// GetConsensusState implements clientexported.MsgCreateClient // GetConsensusState implements clientexported.MsgCreateClient
func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState { 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.Header.GetAppHash())
return &ConsensusState{ return &ConsensusState{
Timestamp: msg.Header.Time, Timestamp: msg.Header.GetTime(),
Root: root, Root: root,
Height: uint64(msg.Header.Height), Height: msg.Header.GetHeight(),
NextValidatorsHash: msg.Header.NextValidatorsHash, NextValidatorsHash: msg.Header.Header.NextValidatorsHash,
} }
} }
// InitializeFromMsg creates a tendermint client state from a CreateClientMsg // InitializeFromMsg creates a tendermint client state from a CreateClientMsg
func (msg MsgCreateClient) InitializeClientState() clientexported.ClientState { func (msg MsgCreateClient) InitializeClientState() clientexported.ClientState {
return NewClientState(msg.Header.ChainID, msg.TrustLevel, return NewClientState(msg.Header.Header.GetChainID(), msg.TrustLevel,
msg.TrustingPeriod, msg.UnbondingPeriod, msg.MaxClockDrift, msg.TrustingPeriod, msg.UnbondingPeriod, msg.MaxClockDrift,
uint64(msg.Header.Height), msg.ProofSpecs, msg.Header.GetHeight(), msg.ProofSpecs,
) )
} }

View File

@ -14,7 +14,7 @@ import (
func (suite *TendermintTestSuite) TestMsgCreateClientValidateBasic() { func (suite *TendermintTestSuite) TestMsgCreateClientValidateBasic() {
privKey := secp256k1.GenPrivKey() privKey := secp256k1.GenPrivKey()
signer := sdk.AccAddress(privKey.PubKey().Address()) signer := sdk.AccAddress(privKey.PubKey().Address())
invalidHeader := types.CreateTestHeader(suite.header.ChainID, height, 0, suite.now, suite.valSet, nil, []tmtypes.PrivValidator{suite.privVal}) invalidHeader := types.CreateTestHeader(suite.header.Header.GetChainID(), height, 0, suite.now, suite.valSet, nil, []tmtypes.PrivValidator{suite.privVal})
invalidHeader.ValidatorSet = nil invalidHeader.ValidatorSet = nil
cases := []struct { cases := []struct {

View File

@ -13,6 +13,7 @@ import (
_ "github.com/golang/protobuf/ptypes/duration" _ "github.com/golang/protobuf/ptypes/duration"
_ "github.com/golang/protobuf/ptypes/timestamp" _ "github.com/golang/protobuf/ptypes/timestamp"
github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes" github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes"
types1 "github.com/tendermint/tendermint/proto/tendermint/types"
io "io" io "io"
math "math" math "math"
math_bits "math/bits" math_bits "math/bits"
@ -129,6 +130,79 @@ func (m *ConsensusState) XXX_DiscardUnknown() {
var xxx_messageInfo_ConsensusState proto.InternalMessageInfo var xxx_messageInfo_ConsensusState proto.InternalMessageInfo
// Header defines the Tendermint client consensus Header.
// It encapsulates all the information necessary to update from a trusted
// Tendermint ConsensusState. The inclusion of TrustedHeight and
// TrustedValidators allows this update to process correctly, so long as the
// ConsensusState for the TrustedHeight exists, this removes race conditions
// among relayers The SignedHeader and ValidatorSet are the new untrusted update
// fields for the client. The TrustedHeight is the height of a stored
// ConsensusState on the client that will be used to verify the new untrusted
// header. The Trusted ConsensusState must be within the unbonding period of
// current time in order to correctly verify, and the TrustedValidators must
// hash to TrustedConsensusState.NextValidatorsHash since that is the last
// trusted validator set at the TrustedHeight.
type Header struct {
types1.SignedHeader `protobuf:"bytes,1,opt,name=signed_header,json=signedHeader,proto3,embedded=signed_header" json:"signed_header" yaml:"signed_header"`
ValidatorSet *types1.ValidatorSet `protobuf:"bytes,2,opt,name=validator_set,json=validatorSet,proto3" json:"validator_set,omitempty" yaml:"validator_set"`
TrustedHeight uint64 `protobuf:"varint,3,opt,name=trusted_height,json=trustedHeight,proto3" json:"trusted_height,omitempty" yaml:"trusted_height"`
TrustedValidators *types1.ValidatorSet `protobuf:"bytes,4,opt,name=trusted_validators,json=trustedValidators,proto3" json:"trusted_validators,omitempty" yaml:"trusted_validators"`
}
func (m *Header) Reset() { *m = Header{} }
func (m *Header) String() string { return proto.CompactTextString(m) }
func (*Header) ProtoMessage() {}
func (*Header) Descriptor() ([]byte, []int) {
return fileDescriptor_76a953d5a747dd66, []int{2}
}
func (m *Header) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Header.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Header) XXX_Merge(src proto.Message) {
xxx_messageInfo_Header.Merge(m, src)
}
func (m *Header) XXX_Size() int {
return m.Size()
}
func (m *Header) XXX_DiscardUnknown() {
xxx_messageInfo_Header.DiscardUnknown(m)
}
var xxx_messageInfo_Header proto.InternalMessageInfo
func (m *Header) GetValidatorSet() *types1.ValidatorSet {
if m != nil {
return m.ValidatorSet
}
return nil
}
func (m *Header) GetTrustedHeight() uint64 {
if m != nil {
return m.TrustedHeight
}
return 0
}
func (m *Header) GetTrustedValidators() *types1.ValidatorSet {
if m != nil {
return m.TrustedValidators
}
return nil
}
// Fraction defines the protobuf message type for tmmath.Fraction // Fraction defines the protobuf message type for tmmath.Fraction
type Fraction struct { type Fraction struct {
Numerator int64 `protobuf:"varint,1,opt,name=numerator,proto3" json:"numerator,omitempty"` Numerator int64 `protobuf:"varint,1,opt,name=numerator,proto3" json:"numerator,omitempty"`
@ -139,7 +213,7 @@ func (m *Fraction) Reset() { *m = Fraction{} }
func (m *Fraction) String() string { return proto.CompactTextString(m) } func (m *Fraction) String() string { return proto.CompactTextString(m) }
func (*Fraction) ProtoMessage() {} func (*Fraction) ProtoMessage() {}
func (*Fraction) Descriptor() ([]byte, []int) { func (*Fraction) Descriptor() ([]byte, []int) {
return fileDescriptor_76a953d5a747dd66, []int{2} return fileDescriptor_76a953d5a747dd66, []int{3}
} }
func (m *Fraction) XXX_Unmarshal(b []byte) error { func (m *Fraction) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -185,57 +259,67 @@ func (m *Fraction) GetDenominator() int64 {
func init() { func init() {
proto.RegisterType((*ClientState)(nil), "ibc.tendermint.ClientState") proto.RegisterType((*ClientState)(nil), "ibc.tendermint.ClientState")
proto.RegisterType((*ConsensusState)(nil), "ibc.tendermint.ConsensusState") proto.RegisterType((*ConsensusState)(nil), "ibc.tendermint.ConsensusState")
proto.RegisterType((*Header)(nil), "ibc.tendermint.Header")
proto.RegisterType((*Fraction)(nil), "ibc.tendermint.Fraction") proto.RegisterType((*Fraction)(nil), "ibc.tendermint.Fraction")
} }
func init() { proto.RegisterFile("ibc/tendermint/tendermint.proto", fileDescriptor_76a953d5a747dd66) } func init() { proto.RegisterFile("ibc/tendermint/tendermint.proto", fileDescriptor_76a953d5a747dd66) }
var fileDescriptor_76a953d5a747dd66 = []byte{ var fileDescriptor_76a953d5a747dd66 = []byte{
// 698 bytes of a gzipped FileDescriptorProto // 845 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x4e, 0xdb, 0x4c, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcd, 0x6e, 0xe4, 0x44,
0x14, 0x8d, 0x21, 0x40, 0x18, 0xf3, 0x27, 0x7f, 0x88, 0xcf, 0xa4, 0x95, 0x1d, 0xb9, 0x9b, 0x6c, 0x10, 0x1e, 0x27, 0xb3, 0xd9, 0xa4, 0x67, 0x26, 0x59, 0x9a, 0x10, 0x9c, 0x61, 0xb1, 0x47, 0xe6,
0xb0, 0xab, 0x80, 0x5a, 0x09, 0xa9, 0x1b, 0x83, 0x2a, 0xa8, 0x5a, 0x09, 0x99, 0xfe, 0x48, 0xdd, 0x92, 0xcb, 0xda, 0x28, 0xbb, 0x02, 0x69, 0x25, 0x24, 0xe4, 0xac, 0x50, 0x16, 0x81, 0x14, 0x79,
0x58, 0xfe, 0x99, 0xd8, 0x23, 0xec, 0x19, 0xcb, 0x33, 0x46, 0xa1, 0x4f, 0x40, 0x77, 0x2c, 0xbb, 0xf8, 0x91, 0x90, 0x90, 0xe5, 0x9f, 0x1e, 0xbb, 0x15, 0xbb, 0xdb, 0x72, 0xf7, 0x44, 0x13, 0x9e,
0xec, 0x43, 0xf4, 0x21, 0x58, 0xb2, 0xec, 0x2a, 0xad, 0xe0, 0x0d, 0x58, 0x76, 0x55, 0xcd, 0xd8, 0x60, 0xb9, 0xed, 0x91, 0x23, 0x0f, 0xc1, 0x43, 0xec, 0x31, 0x47, 0x4e, 0x06, 0x25, 0x6f, 0x30,
0x26, 0x26, 0x45, 0xaa, 0xba, 0xca, 0xdc, 0x73, 0xcf, 0xb9, 0x77, 0xee, 0xcd, 0xf1, 0x00, 0x1d, 0x47, 0x0e, 0x08, 0x75, 0xbb, 0x3d, 0xf6, 0xcc, 0x46, 0x5a, 0x71, 0x49, 0xba, 0xbe, 0xfa, 0xaa,
0xf9, 0x81, 0xc5, 0x20, 0x0e, 0x61, 0x9e, 0x22, 0xcc, 0x1a, 0x47, 0x33, 0xcb, 0x09, 0x23, 0xca, 0xca, 0x55, 0xfd, 0x55, 0x0f, 0x30, 0x71, 0x18, 0x39, 0x1c, 0x91, 0x18, 0x95, 0x39, 0x26, 0xbc,
0x0a, 0xf2, 0x03, 0x73, 0x82, 0x76, 0xff, 0x0b, 0x08, 0x1e, 0x22, 0x62, 0x65, 0x39, 0x21, 0x43, 0x73, 0xb4, 0x8b, 0x92, 0x72, 0x0a, 0xf7, 0x71, 0x18, 0xd9, 0x2d, 0x3a, 0x9e, 0x74, 0xc9, 0xd7,
0x5a, 0x92, 0xba, 0x5a, 0x44, 0x48, 0x94, 0x40, 0x4b, 0x44, 0x7e, 0x31, 0xb4, 0xc2, 0x22, 0xf7, 0x05, 0x62, 0xce, 0x55, 0x90, 0xe1, 0x38, 0xe0, 0xb4, 0xac, 0x23, 0xc6, 0x8f, 0xdf, 0x62, 0xc8,
0x18, 0x22, 0xb8, 0xca, 0xeb, 0xd3, 0x79, 0x86, 0x52, 0x48, 0x99, 0x97, 0x66, 0x35, 0x81, 0x5f, 0xbf, 0xca, 0xfb, 0x7e, 0x44, 0xc9, 0x0c, 0x53, 0xa7, 0x28, 0x29, 0x9d, 0x35, 0xa0, 0x91, 0x50,
0x23, 0x20, 0x69, 0x8a, 0x58, 0x0a, 0x31, 0x6b, 0x1c, 0x2b, 0xc2, 0x7a, 0x44, 0x22, 0x22, 0x8e, 0x9a, 0x64, 0xc8, 0x91, 0x56, 0x38, 0x9f, 0x39, 0xf1, 0xbc, 0x0c, 0x38, 0xa6, 0x44, 0xf9, 0xcd,
0x16, 0x3f, 0x95, 0xa8, 0x71, 0x3e, 0x07, 0xe4, 0xbd, 0x04, 0x41, 0xcc, 0x8e, 0x99, 0xc7, 0xa0, 0x4d, 0x3f, 0xc7, 0x39, 0x62, 0x3c, 0xc8, 0x8b, 0x86, 0x20, 0xda, 0x88, 0x68, 0x9e, 0x63, 0x9e,
0xb2, 0x09, 0x3a, 0x41, 0xec, 0x21, 0xec, 0xa2, 0x50, 0x95, 0x7a, 0x52, 0x7f, 0xd1, 0x59, 0x10, 0x23, 0xc2, 0x3b, 0x47, 0x45, 0x38, 0x4c, 0x68, 0x42, 0xe5, 0xd1, 0x11, 0xa7, 0x1a, 0xb5, 0x5e,
0xf1, 0x61, 0xa8, 0xbc, 0x03, 0x32, 0xcb, 0x0b, 0xca, 0xdc, 0x04, 0x9e, 0xc2, 0x44, 0x9d, 0xe9, 0x3d, 0x00, 0x83, 0xb3, 0x0c, 0x23, 0xc2, 0xa7, 0x3c, 0xe0, 0x08, 0x1e, 0x83, 0xdd, 0x28, 0x0d,
0x49, 0x7d, 0x79, 0xa0, 0x9a, 0xf7, 0xa7, 0x33, 0x5f, 0xe6, 0x5e, 0xc0, 0xef, 0x6d, 0x77, 0x2f, 0x30, 0xf1, 0x71, 0xac, 0x6b, 0x13, 0xed, 0x64, 0xcf, 0x7b, 0x28, 0xed, 0x97, 0x31, 0xfc, 0x1e,
0xc7, 0x7a, 0xeb, 0x76, 0xac, 0x2b, 0x67, 0x5e, 0x9a, 0xec, 0x1a, 0x0d, 0xa9, 0xe1, 0x00, 0x11, 0x0c, 0x78, 0x39, 0x67, 0xdc, 0xcf, 0xd0, 0x15, 0xca, 0xf4, 0xad, 0x89, 0x76, 0x32, 0x38, 0xd5,
0xbd, 0xe6, 0x81, 0x32, 0x04, 0xab, 0x22, 0x42, 0x38, 0x72, 0x33, 0x98, 0x23, 0x12, 0xaa, 0xb3, 0xed, 0xf5, 0xe9, 0xd8, 0x5f, 0x95, 0x41, 0x24, 0xbe, 0xdb, 0x1d, 0xbf, 0xa9, 0xcc, 0xde, 0xb2,
0xa2, 0xf4, 0xa6, 0x59, 0xce, 0x6c, 0xd6, 0x33, 0x9b, 0xfb, 0xd5, 0x4e, 0x6c, 0xa3, 0xaa, 0xbd, 0x32, 0xe1, 0x75, 0x90, 0x67, 0xcf, 0xad, 0x4e, 0xa8, 0xe5, 0x01, 0x69, 0x7d, 0x23, 0x0c, 0x38,
0xd1, 0xa8, 0x3d, 0xd1, 0x1b, 0x5f, 0x7e, 0xe8, 0x92, 0xb3, 0x52, 0xa3, 0x47, 0x02, 0x54, 0x10, 0x03, 0x07, 0xd2, 0xc2, 0x24, 0xf1, 0x0b, 0x54, 0x62, 0x1a, 0xeb, 0xdb, 0x32, 0xf5, 0xb1, 0x5d,
0x58, 0x2b, 0xb0, 0x4f, 0x70, 0xd8, 0x68, 0xd4, 0xfe, 0x5b, 0xa3, 0x27, 0x55, 0xa3, 0xff, 0xcb, 0xf7, 0x6c, 0x37, 0x3d, 0xdb, 0x2f, 0xd4, 0x4c, 0x5c, 0x4b, 0xe5, 0x3e, 0xea, 0xe4, 0x6e, 0xe3,
0x46, 0xd3, 0x05, 0xca, 0x4e, 0xab, 0x77, 0x70, 0xd5, 0x0a, 0x82, 0xd5, 0xd4, 0x1b, 0xb9, 0x41, 0xad, 0xdf, 0xfe, 0x32, 0x35, 0x6f, 0xbf, 0x41, 0x2f, 0x24, 0x08, 0x31, 0x78, 0x34, 0x27, 0x21,
0x42, 0x82, 0x13, 0x37, 0xcc, 0xd1, 0x90, 0xa9, 0x73, 0xff, 0x38, 0xd2, 0x94, 0xbe, 0x6c, 0xb4, 0x25, 0x71, 0xa7, 0x50, 0xff, 0x5d, 0x85, 0x3e, 0x51, 0x85, 0x3e, 0xac, 0x0b, 0x6d, 0x26, 0xa8,
0x9c, 0x7a, 0xa3, 0x3d, 0x0e, 0xee, 0x73, 0x4c, 0x79, 0x01, 0x96, 0x87, 0x39, 0xf9, 0x04, 0xb1, 0x2b, 0x1d, 0xac, 0x60, 0x55, 0x0a, 0x81, 0x83, 0x3c, 0x58, 0xf8, 0x51, 0x46, 0xa3, 0x4b, 0x3f,
0x1b, 0x43, 0x14, 0xc5, 0x4c, 0x9d, 0xef, 0x49, 0xfd, 0xb6, 0xad, 0xde, 0x8e, 0xf5, 0xf5, 0xb2, 0x2e, 0xf1, 0x8c, 0xeb, 0x0f, 0xfe, 0x67, 0x4b, 0x1b, 0xf1, 0x75, 0xa1, 0x51, 0x1e, 0x2c, 0xce,
0xca, 0xbd, 0xb4, 0xe1, 0x2c, 0x95, 0xf1, 0x81, 0x08, 0xb9, 0x3c, 0xf1, 0x18, 0xa4, 0xac, 0x96, 0x04, 0xf8, 0x42, 0x60, 0xf0, 0x0b, 0x30, 0x9a, 0x95, 0xf4, 0x17, 0x44, 0xfc, 0x14, 0xe1, 0x24,
0x2f, 0x4c, 0xcb, 0xef, 0xa5, 0x0d, 0x67, 0xa9, 0x8c, 0x2b, 0xf9, 0x21, 0x90, 0x85, 0x83, 0x5d, 0xe5, 0xfa, 0xce, 0x44, 0x3b, 0xe9, 0xbb, 0xfa, 0xb2, 0x32, 0x0f, 0xeb, 0x2c, 0x6b, 0x6e, 0xcb,
0x9a, 0xc1, 0x80, 0xaa, 0x9d, 0xde, 0x6c, 0x5f, 0x1e, 0xac, 0x99, 0x28, 0xa0, 0x83, 0x6d, 0xf3, 0x1b, 0xd6, 0xf6, 0xb9, 0x34, 0x45, 0x78, 0x16, 0x70, 0xc4, 0x78, 0x13, 0xfe, 0x70, 0x33, 0x7c,
0x88, 0x67, 0x8e, 0x33, 0x18, 0xd8, 0x1b, 0x13, 0x0b, 0x34, 0xe8, 0x86, 0x03, 0xb2, 0x9a, 0x42, 0xcd, 0x6d, 0x79, 0xc3, 0xda, 0x56, 0xe1, 0x2f, 0xc1, 0x40, 0x2a, 0xd8, 0x67, 0x05, 0x8a, 0x98,
0x77, 0xdb, 0xe7, 0x5f, 0xf5, 0x96, 0xf1, 0x6d, 0x06, 0xac, 0xec, 0x11, 0x4c, 0x21, 0xa6, 0x05, 0xbe, 0x3b, 0xd9, 0x3e, 0x19, 0x9c, 0x3e, 0xb2, 0x71, 0xc4, 0x4e, 0x9f, 0xda, 0x17, 0xc2, 0x33,
0x2d, 0xdd, 0x68, 0x83, 0xc5, 0x3b, 0x9f, 0x0b, 0x3b, 0xca, 0x83, 0xee, 0x1f, 0x2b, 0x7c, 0x5b, 0x2d, 0x50, 0xe4, 0x1e, 0xb5, 0x12, 0xe8, 0xd0, 0x2d, 0x0f, 0x14, 0x0d, 0x85, 0x3d, 0xef, 0xbf,
0x33, 0xec, 0x0e, 0xdf, 0xe1, 0x05, 0xdf, 0xd4, 0x44, 0xa6, 0xec, 0x80, 0x76, 0x4e, 0x08, 0xab, 0xfa, 0xdd, 0xec, 0x59, 0x7f, 0x6c, 0x81, 0xfd, 0x33, 0x4a, 0x18, 0x22, 0x6c, 0xce, 0x6a, 0x35,
0xfc, 0xda, 0x15, 0x7e, 0x6d, 0x7c, 0x1c, 0x6f, 0x60, 0x7e, 0x92, 0x40, 0x87, 0x10, 0x66, 0xb7, 0xba, 0x60, 0x6f, 0xa5, 0x73, 0x29, 0xc7, 0xc1, 0xe9, 0xf8, 0xad, 0x11, 0x7e, 0xd7, 0x30, 0xdc,
0xb9, 0xdc, 0x11, 0x6c, 0x65, 0x03, 0xcc, 0x57, 0x5b, 0xe1, 0x66, 0x6c, 0x3b, 0x55, 0xa4, 0x7c, 0x5d, 0x31, 0xc3, 0xd7, 0x62, 0x52, 0x6d, 0x18, 0x7c, 0x06, 0xfa, 0x25, 0xa5, 0x5c, 0xe9, 0x75,
0x96, 0xc0, 0x3a, 0x86, 0x23, 0xe6, 0x9e, 0x7a, 0x09, 0x0a, 0x3d, 0x46, 0x72, 0xea, 0xc6, 0x1e, 0x2c, 0xf5, 0xda, 0x59, 0x8e, 0x6f, 0x51, 0x79, 0x99, 0x21, 0x8f, 0x52, 0xee, 0xf6, 0x45, 0xb8,
0x8d, 0x85, 0x95, 0x96, 0xec, 0x0f, 0xb7, 0x63, 0xfd, 0x51, 0x39, 0xed, 0x43, 0x2c, 0xe3, 0xd7, 0x27, 0xd9, 0xf0, 0x08, 0xec, 0xa8, 0xa9, 0x08, 0x31, 0xf6, 0x3d, 0x65, 0xc1, 0x5f, 0x35, 0x70,
0x58, 0xdf, 0x89, 0x10, 0x8b, 0x0b, 0x9f, 0xdf, 0xe1, 0xe1, 0x67, 0xc3, 0x4a, 0x90, 0x4f, 0x2d, 0x48, 0xd0, 0x82, 0xfb, 0xab, 0x9d, 0x67, 0x7e, 0x1a, 0xb0, 0x54, 0x4a, 0x69, 0xe8, 0xfe, 0xb8,
0xff, 0x8c, 0x41, 0x6a, 0x1e, 0xc0, 0x91, 0xcd, 0x0f, 0x8e, 0xc2, 0xcb, 0xbd, 0xbf, 0xab, 0x76, 0xac, 0xcc, 0x8f, 0xea, 0x6e, 0xef, 0x63, 0x59, 0xff, 0x54, 0xe6, 0xb3, 0x04, 0xf3, 0x74, 0x1e,
0xe0, 0xd1, 0xb8, 0x5a, 0xdb, 0x2b, 0xd0, 0xa9, 0xbf, 0x39, 0xe5, 0x31, 0x58, 0xc4, 0x45, 0x0a, 0x8a, 0x6f, 0xb8, 0xff, 0xd9, 0x71, 0x32, 0x1c, 0x32, 0x27, 0xbc, 0xe6, 0x88, 0xd9, 0xe7, 0x68,
0x73, 0xce, 0x11, 0xfb, 0x9a, 0x75, 0x26, 0x80, 0xd2, 0x03, 0x72, 0x08, 0x31, 0x49, 0x11, 0x16, 0xe1, 0x8a, 0x83, 0x07, 0x45, 0xba, 0x1f, 0x56, 0xd9, 0xce, 0x03, 0x96, 0xaa, 0xb1, 0xfd, 0xbb,
0xf9, 0x19, 0x91, 0x6f, 0x42, 0xf6, 0xd1, 0xe5, 0xb5, 0x26, 0x5d, 0x5d, 0x6b, 0xd2, 0xcf, 0x6b, 0x05, 0x76, 0xce, 0x51, 0x10, 0xa3, 0x12, 0x22, 0x30, 0x62, 0x38, 0x21, 0x28, 0xf6, 0x53, 0x09,
0x4d, 0xba, 0xb8, 0xd1, 0x5a, 0x57, 0x37, 0x5a, 0xeb, 0xfb, 0x8d, 0xd6, 0xfa, 0xf8, 0xac, 0x71, 0xa8, 0x91, 0x19, 0xdd, 0xfd, 0xac, 0x5f, 0xa2, 0xa9, 0xa4, 0xd5, 0x61, 0xee, 0x44, 0xf4, 0x7d,
0xeb, 0x80, 0xd0, 0x94, 0xd0, 0xea, 0x67, 0x8b, 0x86, 0x27, 0xd6, 0xc8, 0xe2, 0xaf, 0xcf, 0xd3, 0x53, 0x99, 0x5a, 0x7b, 0xf3, 0x6b, 0x69, 0x2c, 0x6f, 0xc8, 0x3a, 0x7c, 0xf8, 0x33, 0x18, 0xad,
0xe7, 0x5b, 0xcd, 0x81, 0xce, 0x32, 0x48, 0xfd, 0x79, 0xf1, 0x37, 0x6d, 0xff, 0x0e, 0x00, 0x00, 0xfa, 0xf2, 0x19, 0x6a, 0x46, 0x7b, 0x4f, 0x99, 0xd5, 0x07, 0x4f, 0x11, 0xef, 0x0a, 0x6b, 0x2d,
0xff, 0xff, 0x07, 0xd7, 0x7b, 0xa7, 0x26, 0x05, 0x00, 0x00, 0xdc, 0xf2, 0x86, 0x57, 0x1d, 0x1e, 0xfc, 0x12, 0xd4, 0xab, 0x2b, 0xeb, 0xb7, 0x57, 0xe0, 0x1e,
0x2f, 0x2b, 0xf3, 0x83, 0xce, 0xc2, 0xaf, 0xfc, 0x96, 0x37, 0x52, 0x80, 0x92, 0x66, 0x06, 0x60,
0xc3, 0x68, 0x2f, 0x40, 0x2d, 0xfb, 0xbb, 0xbe, 0xf2, 0xe3, 0x65, 0x65, 0x1e, 0xaf, 0x57, 0x69,
0x73, 0x58, 0xde, 0x7b, 0x0a, 0x6c, 0xaf, 0xc2, 0xfa, 0x1a, 0xec, 0x36, 0x8f, 0x1e, 0x7c, 0x0c,
0xf6, 0xc8, 0x3c, 0x47, 0xa5, 0xf0, 0xc8, 0xe9, 0x6f, 0x7b, 0x2d, 0x00, 0x27, 0x60, 0x10, 0x23,
0x42, 0x73, 0x4c, 0xa4, 0x7f, 0x4b, 0xfa, 0xbb, 0x90, 0x7b, 0xf1, 0xe6, 0xd6, 0xd0, 0x6e, 0x6e,
0x0d, 0xed, 0xef, 0x5b, 0x43, 0x7b, 0x7d, 0x67, 0xf4, 0x6e, 0xee, 0x8c, 0xde, 0x9f, 0x77, 0x46,
0xef, 0xa7, 0xcf, 0x3a, 0xb2, 0x89, 0x28, 0xcb, 0x29, 0x53, 0xff, 0x9e, 0xb0, 0xf8, 0xd2, 0x59,
0x38, 0xe2, 0xf9, 0xff, 0xf4, 0xf3, 0x27, 0x9b, 0xbf, 0x3c, 0xe1, 0x8e, 0xdc, 0x93, 0xa7, 0xff,
0x05, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x78, 0x14, 0xd9, 0xe7, 0x06, 0x00, 0x00,
} }
func (m *ClientState) Marshal() (dAtA []byte, err error) { func (m *ClientState) Marshal() (dAtA []byte, err error) {
@ -379,6 +463,68 @@ func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *Header) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Header) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.TrustedValidators != nil {
{
size, err := m.TrustedValidators.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTendermint(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x22
}
if m.TrustedHeight != 0 {
i = encodeVarintTendermint(dAtA, i, uint64(m.TrustedHeight))
i--
dAtA[i] = 0x18
}
if m.ValidatorSet != nil {
{
size, err := m.ValidatorSet.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTendermint(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
{
size, err := m.SignedHeader.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTendermint(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *Fraction) Marshal() (dAtA []byte, err error) { func (m *Fraction) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
@ -476,6 +622,28 @@ func (m *ConsensusState) Size() (n int) {
return n return n
} }
func (m *Header) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = m.SignedHeader.Size()
n += 1 + l + sovTendermint(uint64(l))
if m.ValidatorSet != nil {
l = m.ValidatorSet.Size()
n += 1 + l + sovTendermint(uint64(l))
}
if m.TrustedHeight != 0 {
n += 1 + sovTendermint(uint64(m.TrustedHeight))
}
if m.TrustedValidators != nil {
l = m.TrustedValidators.Size()
n += 1 + l + sovTendermint(uint64(l))
}
return n
}
func (m *Fraction) Size() (n int) { func (m *Fraction) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
@ -958,6 +1126,183 @@ func (m *ConsensusState) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *Header) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTendermint
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Header: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field SignedHeader", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTendermint
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTendermint
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTendermint
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.SignedHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSet", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTendermint
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTendermint
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTendermint
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.ValidatorSet == nil {
m.ValidatorSet = &types1.ValidatorSet{}
}
if err := m.ValidatorSet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field TrustedHeight", wireType)
}
m.TrustedHeight = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTendermint
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.TrustedHeight |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TrustedValidators", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTendermint
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTendermint
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTendermint
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.TrustedValidators == nil {
m.TrustedValidators = &types1.ValidatorSet{}
}
if err := m.TrustedValidators.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTendermint(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTendermint
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthTendermint
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Fraction) Unmarshal(dAtA []byte) error { func (m *Fraction) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0

View File

@ -10,7 +10,7 @@ import (
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
) )
// Copied unimported test functions from tmtypes to use them here // MakeBlockID is a copied unimported test function from tmtypes to use here
func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.BlockID { func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.BlockID {
return tmtypes.BlockID{ return tmtypes.BlockID{
Hash: hash, Hash: hash,
@ -22,8 +22,12 @@ func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.Bl
} }
// CreateTestHeader creates a mock header for testing only. // CreateTestHeader creates a mock header for testing only.
func CreateTestHeader(chainID string, height, trustedHeight int64, timestamp time.Time, valSet, trustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header { func CreateTestHeader(chainID string, height, trustedHeight int64, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) Header {
vsetHash := valSet.Hash() var (
valSet *tmproto.ValidatorSet
trustedVals *tmproto.ValidatorSet
)
vsetHash := tmValSet.Hash()
tmHeader := tmtypes.Header{ tmHeader := tmtypes.Header{
Version: version.Consensus{Block: 2, App: 2}, Version: version.Consensus{Block: 2, App: 2},
ChainID: chainID, ChainID: chainID,
@ -38,20 +42,34 @@ func CreateTestHeader(chainID string, height, trustedHeight int64, timestamp tim
AppHash: tmhash.Sum([]byte("app_hash")), AppHash: tmhash.Sum([]byte("app_hash")),
LastResultsHash: tmhash.Sum([]byte("last_results_hash")), LastResultsHash: tmhash.Sum([]byte("last_results_hash")),
EvidenceHash: tmhash.Sum([]byte("evidence_hash")), EvidenceHash: tmhash.Sum([]byte("evidence_hash")),
ProposerAddress: valSet.Proposer.Address, ProposerAddress: tmValSet.Proposer.Address,
} }
hhash := tmHeader.Hash() hhash := tmHeader.Hash()
blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set")))
voteSet := tmtypes.NewVoteSet(chainID, height, 1, tmproto.PrecommitType, valSet) voteSet := tmtypes.NewVoteSet(chainID, height, 1, tmproto.PrecommitType, tmValSet)
commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers, timestamp) commit, err := tmtypes.MakeCommit(blockID, height, 1, voteSet, signers, timestamp)
if err != nil { if err != nil {
panic(err) panic(err)
} }
signedHeader := tmtypes.SignedHeader{ signedHeader := tmproto.SignedHeader{
Header: &tmHeader, Header: tmHeader.ToProto(),
Commit: commit, Commit: commit.ToProto(),
}
if tmValSet != nil {
valSet, err = tmValSet.ToProto()
if err != nil {
panic(err)
}
}
if tmTrustedVals != nil {
trustedVals, err = tmTrustedVals.ToProto()
if err != nil {
panic(err)
}
} }
return Header{ return Header{

View File

@ -70,9 +70,15 @@ func checkTrustedHeader(header Header, consState *ConsensusState) error {
header.TrustedHeight, consState.Height, header.TrustedHeight, consState.Height,
) )
} }
tmTrustedValidators, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators)
if err != nil {
return sdkerrors.Wrap(err, "trusted validator set in not tendermint validator set type")
}
// assert that trustedVals is NextValidators of last trusted header // assert that trustedVals is NextValidators of last trusted header
// to do this, we check that trustedVals.Hash() == consState.NextValidatorsHash // to do this, we check that trustedVals.Hash() == consState.NextValidatorsHash
tvalHash := header.TrustedValidators.Hash() tvalHash := tmTrustedValidators.Hash()
if !bytes.Equal(consState.NextValidatorsHash, tvalHash) { if !bytes.Equal(consState.NextValidatorsHash, tvalHash) {
return sdkerrors.Wrapf( return sdkerrors.Wrapf(
ErrInvalidValidatorSet, ErrInvalidValidatorSet,
@ -93,6 +99,21 @@ func checkValidity(
return err return err
} }
tmTrustedValidators, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators)
if err != nil {
return sdkerrors.Wrap(err, "trusted validator set in not tendermint validator set type")
}
tmSignedHeader, err := tmtypes.SignedHeaderFromProto(&header.SignedHeader)
if err != nil {
return sdkerrors.Wrap(err, "signed header in not tendermint signed header type")
}
tmValidatorSet, err := tmtypes.ValidatorSetFromProto(header.ValidatorSet)
if err != nil {
return sdkerrors.Wrap(err, "validator set in not tendermint validator set type")
}
// assert header height is newer than consensus state // assert header height is newer than consensus state
if header.GetHeight() <= consState.Height { if header.GetHeight() <= consState.Height {
return sdkerrors.Wrapf( return sdkerrors.Wrapf(
@ -117,9 +138,9 @@ func checkValidity(
// - assert header timestamp is not past the trusting period // - assert header timestamp is not past the trusting period
// - assert header timestamp is past latest stored consensus state timestamp // - assert header timestamp is past latest stored consensus state timestamp
// - assert that a TrustLevel proportion of TrustedValidators signed new Commit // - assert that a TrustLevel proportion of TrustedValidators signed new Commit
err := light.Verify( err = light.Verify(
clientState.GetChainID(), &signedHeader, clientState.GetChainID(), &signedHeader,
header.TrustedValidators, &header.SignedHeader, header.ValidatorSet, tmTrustedValidators, tmSignedHeader, tmValidatorSet,
clientState.TrustingPeriod, currentTimestamp, clientState.MaxClockDrift, clientState.TrustLevel.ToTendermint(), clientState.TrustingPeriod, currentTimestamp, clientState.MaxClockDrift, clientState.TrustLevel.ToTendermint(),
) )
if err != nil { if err != nil {
@ -130,14 +151,14 @@ func checkValidity(
// update the consensus state from a new header // update the consensus state from a new header
func update(clientState *ClientState, header Header) (*ClientState, *ConsensusState) { func update(clientState *ClientState, header Header) (*ClientState, *ConsensusState) {
if uint64(header.Height) > clientState.LatestHeight { if header.GetHeight() > clientState.LatestHeight {
clientState.LatestHeight = uint64(header.Height) clientState.LatestHeight = header.GetHeight()
} }
consensusState := &ConsensusState{ consensusState := &ConsensusState{
Height: uint64(header.Height), Height: header.GetHeight(),
Timestamp: header.Time, Timestamp: header.GetTime(),
Root: commitmenttypes.NewMerkleRoot(header.AppHash), Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()),
NextValidatorsHash: header.NextValidatorsHash, NextValidatorsHash: header.Header.NextValidatorsHash,
} }
return clientState, consensusState return clientState, consensusState

View File

@ -46,7 +46,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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 = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now currentTime = suite.now
}, },
@ -56,7 +56,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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 = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, bothValSet, suite.valSet, bothSigners) newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, bothValSet, suite.valSet, bothSigners)
currentTime = suite.now currentTime = suite.now
}, },
@ -66,7 +66,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "successful update with next height and different validator set", name: "successful update with next height and different validator set",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, bothValSet.Hash()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, bothValSet.Hash())
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, bothValSet, bothValSet, bothSigners) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, bothValSet, bothValSet, bothSigners)
currentTime = suite.now currentTime = suite.now
}, },
@ -76,7 +76,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "successful update for a previous height", name: "successful update for a previous height",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height-3, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height-3, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height-1, height-3, suite.headerTime, bothValSet, suite.valSet, bothSigners) newHeader = types.CreateTestHeader(chainID, height-1, height-3, suite.headerTime, bothValSet, suite.valSet, bothSigners)
currentTime = suite.now currentTime = suite.now
}, },
@ -86,7 +86,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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 = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, bothValSet, suite.valSet, bothSigners) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, bothValSet, suite.valSet, bothSigners)
currentTime = suite.now currentTime = suite.now
}, },
@ -96,7 +96,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "unsuccessful update with next height: update header mismatches different nextValSetHash", name: "unsuccessful update with next height: update header mismatches different nextValSetHash",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, bothValSet.Hash()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, bothValSet.Hash())
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, bothValSet, signers) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, bothValSet, signers)
currentTime = suite.now currentTime = suite.now
}, },
@ -106,7 +106,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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 = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, altValSet, suite.valSet, altSigners) newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, altValSet, suite.valSet, altSigners)
currentTime = suite.now currentTime = suite.now
}, },
@ -116,7 +116,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state", name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, bothValSet, bothValSet, bothSigners) newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, bothValSet, bothValSet, bothSigners)
currentTime = suite.now currentTime = suite.now
}, },
@ -126,7 +126,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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 = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, 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(trustingPeriod) currentTime = suite.now.Add(trustingPeriod)
@ -137,7 +137,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "unsuccessful update: header timestamp is past current timestamp", name: "unsuccessful update: header timestamp is past current timestamp",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers)
currentTime = suite.now currentTime = suite.now
}, },
@ -147,7 +147,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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 = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.clientTime, suite.valSet, suite.valSet, signers) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.clientTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now currentTime = suite.now
}, },
@ -157,7 +157,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "header basic validation failed", name: "header basic validation failed",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers) newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, 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
@ -169,7 +169,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
name: "header height < consensus height", name: "header height < consensus height",
setup: func() { setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height+5, commitmenttypes.GetSDKSpecs()) clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height+5, commitmenttypes.GetSDKSpecs())
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.AppHash), height, suite.valsHash) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash)
// Make new header at height less than latest client state // Make new header at height less than latest client state
newHeader = types.CreateTestHeader(chainID, height-1, height, suite.headerTime, suite.valSet, suite.valSet, signers) newHeader = types.CreateTestHeader(chainID, height-1, height, suite.headerTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now currentTime = suite.now
@ -187,13 +187,13 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
ctx := suite.chainA.GetContext().WithBlockTime(currentTime) ctx := suite.chainA.GetContext().WithBlockTime(currentTime)
// Set trusted consensus state in client store // Set trusted consensus state in client store
suite.chainA.App.IBCKeeper.ClientKeeper.SetClientConsensusState(ctx, clientID, consensusState.Height, consensusState) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientConsensusState(ctx, clientID, consensusState.GetHeight(), consensusState)
expectedConsensus := &types.ConsensusState{ expectedConsensus := &types.ConsensusState{
Height: uint64(newHeader.Height), Height: uint64(newHeader.GetHeight()),
Timestamp: newHeader.Time, Timestamp: newHeader.GetTime(),
Root: commitmenttypes.NewMerkleRoot(newHeader.AppHash), Root: commitmenttypes.NewMerkleRoot(newHeader.Header.GetAppHash()),
NextValidatorsHash: newHeader.NextValidatorsHash, NextValidatorsHash: newHeader.Header.NextValidatorsHash,
} }
newClientState, consensusState, err := clientState.CheckHeaderAndUpdateState( newClientState, consensusState, err := clientState.CheckHeaderAndUpdateState(
@ -207,9 +207,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
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)
// Determine if clientState should be updated or not // Determine if clientState should be updated or not
if uint64(newHeader.Height) > clientState.LatestHeight { if uint64(newHeader.GetHeight()) > clientState.LatestHeight {
// Header Height is greater than clientState latest Height, clientState should be updated with header.Height // Header Height is greater than clientState latest Height, clientState should be updated with header.GetHeight()
suite.Require().Equal(uint64(newHeader.Height), newClientState.GetLatestHeight(), "clientstate height did not update") suite.Require().Equal(uint64(newHeader.GetHeight()), newClientState.GetLatestHeight(), "clientstate height did not update")
} else { } else {
// Update will add past consensus state, clientState should not be updated at all // 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(clientState.LatestHeight, newClientState.GetLatestHeight(), "client state height updated for past header")

View File

@ -48,7 +48,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
clientID, clientID,
[]clientexported.ConsensusState{ []clientexported.ConsensusState{
ibctmtypes.NewConsensusState( ibctmtypes.NewConsensusState(
suite.header.Time, commitmenttypes.NewMerkleRoot(suite.header.AppHash), suite.header.GetHeight(), suite.header.NextValidatorsHash, suite.header.GetTime(), commitmenttypes.NewMerkleRoot(suite.header.Header.AppHash), suite.header.GetHeight(), suite.header.Header.NextValidatorsHash,
), ),
}, },
), ),
@ -177,7 +177,7 @@ func (suite *IBCTestSuite) TestInitGenesis() {
clientID, clientID,
[]clientexported.ConsensusState{ []clientexported.ConsensusState{
ibctmtypes.NewConsensusState( ibctmtypes.NewConsensusState(
suite.header.Time, commitmenttypes.NewMerkleRoot(suite.header.AppHash), suite.header.GetHeight(), suite.header.ValidatorSet.Hash(), suite.header.GetTime(), commitmenttypes.NewMerkleRoot(suite.header.Header.AppHash), suite.header.GetHeight(), suite.header.Header.NextValidatorsHash,
), ),
}, },
), ),

View File

@ -356,26 +356,31 @@ func (chain *TestChain) UpdateTMClient(counterparty *TestChain, clientID string)
// Relayer must query for LatestHeight on client to get TrustedHeight // Relayer must query for LatestHeight on client to get TrustedHeight
trustedHeight := chain.GetClientState(clientID).GetLatestHeight() trustedHeight := chain.GetClientState(clientID).GetLatestHeight()
var ( var (
trustedVals *tmtypes.ValidatorSet tmTrustedVals *tmtypes.ValidatorSet
ok bool ok bool
) )
// Once we get TrustedHeight from client, we must query the validators from the counterparty chain // Once we get TrustedHeight from client, we must query the validators from the counterparty chain
// If the LatestHeight == LastHeader.Height, then TrustedValidators are current validators // If the LatestHeight == LastHeader.Height, then TrustedValidators are current validators
// If LatestHeight < LastHeader.Height, we can query the historical validator set from HistoricalInfo // If LatestHeight < LastHeader.Height, we can query the historical validator set from HistoricalInfo
if trustedHeight == uint64(counterparty.LastHeader.Height) { if trustedHeight == counterparty.LastHeader.GetHeight() {
trustedVals = counterparty.Vals tmTrustedVals = counterparty.Vals
} else { } else {
// NOTE: We need to get validators from counterparty at height: trustedHeight+1 // NOTE: We need to get validators from counterparty at height: trustedHeight+1
// since the last trusted validators for a header at height h // since the last trusted validators for a header at height h
// is the NextValidators at h+1 committed to in header h by // is the NextValidators at h+1 committed to in header h by
// NextValidatorsHash // NextValidatorsHash
trustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight + 1)) tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight + 1))
if !ok { if !ok {
return sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) return sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight)
} }
} }
// inject trusted fields into last header // inject trusted fields into last header
header.TrustedHeight = trustedHeight header.TrustedHeight = trustedHeight
trustedVals, err := tmTrustedVals.ToProto()
if err != nil {
return err
}
header.TrustedValidators = trustedVals header.TrustedValidators = trustedVals
msg := ibctmtypes.NewMsgUpdateClient( msg := ibctmtypes.NewMsgUpdateClient(
@ -414,16 +419,21 @@ func (chain *TestChain) CreateTMClientHeader() ibctmtypes.Header {
commit, err := tmtypes.MakeCommit(blockID, chain.CurrentHeader.Height, 1, voteSet, chain.Signers, chain.CurrentHeader.Time) commit, err := tmtypes.MakeCommit(blockID, chain.CurrentHeader.Height, 1, voteSet, chain.Signers, chain.CurrentHeader.Time)
require.NoError(chain.t, err) require.NoError(chain.t, err)
signedHeader := tmtypes.SignedHeader{ signedHeader := tmproto.SignedHeader{
Header: &tmHeader, Header: tmHeader.ToProto(),
Commit: commit, Commit: commit.ToProto(),
}
valSet, err := chain.Vals.ToProto()
if err != nil {
panic(err)
} }
// Do not set trusted field here, these fields can be inserted before relaying messages to a client. // Do not set trusted field here, these fields can be inserted before relaying messages to a client.
// The relayer is responsible for querying client and injecting appropriate trusted fields. // The relayer is responsible for querying client and injecting appropriate trusted fields.
return ibctmtypes.Header{ return ibctmtypes.Header{
SignedHeader: signedHeader, SignedHeader: signedHeader,
ValidatorSet: chain.Vals, ValidatorSet: valSet,
} }
} }