Implement Connection-specified delay (#8069)

* start with initialization and metadata

* start by fixing delay period during connection handshake

* fix connection handshake tests

* add delay period logic to packet verification

* proto format

* fix err issue

* appease linter

* document upgrade special case

* Update x/ibc/light-clients/07-tendermint/types/client_state.go

Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com>

* Update x/ibc/light-clients/07-tendermint/types/store.go

* add sanity check

* fix build

* fix tests

Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Colin Axner <colinaxner@berkeley.edu>
This commit is contained in:
Aditya 2020-12-07 12:13:06 +00:00 committed by GitHub
parent de114773ee
commit 971d253214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1852 additions and 318 deletions

View File

@ -17,9 +17,30 @@ message GenesisState {
(gogoproto.castrepeated) = "ClientsConsensusStates", (gogoproto.castrepeated) = "ClientsConsensusStates",
(gogoproto.moretags) = "yaml:\"clients_consensus\"" (gogoproto.moretags) = "yaml:\"clients_consensus\""
]; ];
Params params = 3 [(gogoproto.nullable) = false]; // metadata from each client
repeated IdentifiedGenesisMetadata clients_metadata = 3
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"clients_metadata\""];
Params params = 4 [(gogoproto.nullable) = false];
// create localhost on initialization // create localhost on initialization
bool create_localhost = 4 [(gogoproto.moretags) = "yaml:\"create_localhost\""]; bool create_localhost = 5 [(gogoproto.moretags) = "yaml:\"create_localhost\""];
// the sequence for the next generated client identifier // the sequence for the next generated client identifier
uint64 next_client_sequence = 5 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""]; uint64 next_client_sequence = 6 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""];
}
// GenesisMetadata defines the genesis type for metadata that clients may return
// with ExportMetadata
message GenesisMetadata {
option (gogoproto.goproto_getters) = false;
// store key of metadata without clientID-prefix
bytes key = 1;
// metadata value
bytes value = 2;
}
// IdentifiedGenesisMetadata has the client metadata with the corresponding client id.
message IdentifiedGenesisMetadata {
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
repeated GenesisMetadata client_metadata = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_metadata\""];
} }

View File

@ -10,19 +10,23 @@ import "ibc/core/commitment/v1/commitment.proto";
// https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures // https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures
// ConnectionEnd defines a stateful object on a chain connected to another // ConnectionEnd defines a stateful object on a chain connected to another
// separate one. NOTE: there must only be 2 defined ConnectionEnds to establish // separate one.
// NOTE: there must only be 2 defined ConnectionEnds to establish
// a connection between two chains. // a connection between two chains.
message ConnectionEnd { message ConnectionEnd {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
// client associated with this connection. // client associated with this connection.
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// IBC version which can be utilised to determine encodings or protocols for // IBC version which can be utilised to determine encodings or protocols for
// channels or packets utilising this connection // channels or packets utilising this connection.
repeated Version versions = 2; repeated Version versions = 2;
// current state of the connection end. // current state of the connection end.
State state = 3; State state = 3;
// counterparty chain associated with this connection. // counterparty chain associated with this connection.
Counterparty counterparty = 4 [(gogoproto.nullable) = false]; Counterparty counterparty = 4 [(gogoproto.nullable) = false];
// delay period that must pass before a consensus state can be used for packet-verification
// NOTE: delay period logic is only implemented by some clients.
uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""];
} }
// IdentifiedConnection defines a connection with additional connection // IdentifiedConnection defines a connection with additional connection
@ -40,6 +44,8 @@ message IdentifiedConnection {
State state = 4; State state = 4;
// counterparty chain associated with this connection. // counterparty chain associated with this connection.
Counterparty counterparty = 5 [(gogoproto.nullable) = false]; Counterparty counterparty = 5 [(gogoproto.nullable) = false];
// delay period associated with this connection.
uint64 delay_period = 6 [(gogoproto.moretags) = "yaml:\"delay_period\""];
} }
// State defines if a connection is in one of the following states: // State defines if a connection is in one of the following states:
@ -68,7 +74,7 @@ message Counterparty {
// identifies the connection end on the counterparty chain associated with a // identifies the connection end on the counterparty chain associated with a
// given connection. // given connection.
string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""];
// commitment merkle prefix of the counterparty chain // commitment merkle prefix of the counterparty chain.
ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false];
} }

View File

@ -32,7 +32,8 @@ message MsgConnectionOpenInit {
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
Counterparty counterparty = 2 [(gogoproto.nullable) = false]; Counterparty counterparty = 2 [(gogoproto.nullable) = false];
Version version = 3; Version version = 3;
string signer = 4; uint64 delay_period = 4 [(gogoproto.moretags) = "yaml:\"delay_period\""];
string signer = 5;
} }
// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type. // MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type.
@ -50,19 +51,20 @@ message MsgConnectionOpenTry {
string previous_connection_id = 2 [(gogoproto.moretags) = "yaml:\"previous_connection_id\""]; string previous_connection_id = 2 [(gogoproto.moretags) = "yaml:\"previous_connection_id\""];
google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""];
Counterparty counterparty = 4 [(gogoproto.nullable) = false]; Counterparty counterparty = 4 [(gogoproto.nullable) = false];
repeated Version counterparty_versions = 5 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""];
ibc.core.client.v1.Height proof_height = 6 repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""];
ibc.core.client.v1.Height proof_height = 7
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
// proof of the initialization the connection on Chain A: `UNITIALIZED -> // proof of the initialization the connection on Chain A: `UNITIALIZED ->
// INIT` // INIT`
bytes proof_init = 7 [(gogoproto.moretags) = "yaml:\"proof_init\""]; bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""];
// proof of client state included in message // proof of client state included in message
bytes proof_client = 8 [(gogoproto.moretags) = "yaml:\"proof_client\""]; bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""];
// proof of client consensus state // proof of client consensus state
bytes proof_consensus = 9 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""];
ibc.core.client.v1.Height consensus_height = 10 ibc.core.client.v1.Height consensus_height = 11
[(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false];
string signer = 11; string signer = 12;
} }
// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. // MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type.

View File

@ -14,6 +14,12 @@ import (
func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
k.SetParams(ctx, gs.Params) k.SetParams(ctx, gs.Params)
// Set all client metadata first. This will allow client keeper to overwrite client and consensus state keys
// if clients accidentally write to ClientKeeper reserved keys.
if len(gs.ClientsMetadata) != 0 {
k.SetAllClientMetadata(ctx, gs.ClientsMetadata)
}
for _, client := range gs.Clients { for _, client := range gs.Clients {
cs, ok := client.ClientState.GetCachedValue().(exported.ClientState) cs, ok := client.ClientState.GetCachedValue().(exported.ClientState)
if !ok { if !ok {
@ -48,8 +54,14 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
// NOTE: CreateLocalhost should always be false on export since a // NOTE: CreateLocalhost should always be false on export since a
// created localhost will be included in the exported clients. // created localhost will be included in the exported clients.
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
genClients := k.GetAllGenesisClients(ctx)
clientsMetadata, err := k.GetAllClientMetadata(ctx, genClients)
if err != nil {
panic(err)
}
return types.GenesisState{ return types.GenesisState{
Clients: k.GetAllGenesisClients(ctx), Clients: genClients,
ClientsMetadata: clientsMetadata,
ClientsConsensus: k.GetAllConsensusStates(ctx), ClientsConsensus: k.GetAllConsensusStates(ctx),
Params: k.GetParams(ctx), Params: k.GetParams(ctx),
CreateLocalhost: false, CreateLocalhost: false,

View File

@ -12,8 +12,6 @@ import (
// CreateClient creates a new client state and populates it with a given consensus // CreateClient creates a new client state and populates it with a given consensus
// state as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create // state as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create
//
// CONTRACT: ClientState was constructed correctly from given initial consensusState
func (k Keeper) CreateClient( func (k Keeper) CreateClient(
ctx sdk.Context, clientState exported.ClientState, consensusState exported.ConsensusState, ctx sdk.Context, clientState exported.ClientState, consensusState exported.ConsensusState,
) (string, error) { ) (string, error) {
@ -27,12 +25,20 @@ func (k Keeper) CreateClient(
clientID := k.GenerateClientIdentifier(ctx, clientState.ClientType()) clientID := k.GenerateClientIdentifier(ctx, clientState.ClientType())
k.SetClientState(ctx, clientID, clientState)
k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())
// verifies initial consensus state against client state and initializes client store with any client-specific metadata
// e.g. set ProcessedTime in Tendermint clients
if err := clientState.Initialize(ctx, k.cdc, k.ClientStore(ctx, clientID), consensusState); err != nil {
return "", err
}
// check if consensus state is nil in case the created client is Localhost // check if consensus state is nil in case the created client is Localhost
if consensusState != nil { if consensusState != nil {
k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState) k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState)
} }
k.SetClientState(ctx, clientID, clientState)
k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String()) k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())
defer func() { defer func() {

View File

@ -152,6 +152,49 @@ func (k Keeper) GetAllGenesisClients(ctx sdk.Context) types.IdentifiedClientStat
return genClients.Sort() return genClients.Sort()
} }
// GetAllClientMetadata will take a list of IdentifiedClientState and return a list
// of IdentifiedGenesisMetadata necessary for exporting and importing client metadata
// into the client store.
func (k Keeper) GetAllClientMetadata(ctx sdk.Context, genClients []types.IdentifiedClientState) ([]types.IdentifiedGenesisMetadata, error) {
genMetadata := make([]types.IdentifiedGenesisMetadata, 0)
for _, ic := range genClients {
cs, err := types.UnpackClientState(ic.ClientState)
if err != nil {
return nil, err
}
gms := cs.ExportMetadata(k.ClientStore(ctx, ic.ClientId))
if len(gms) == 0 {
continue
}
clientMetadata := make([]types.GenesisMetadata, len(gms))
for i, metadata := range gms {
cmd, ok := metadata.(types.GenesisMetadata)
if !ok {
return nil, sdkerrors.Wrapf(types.ErrInvalidClientMetadata, "expected metadata type: %T, got: %T",
types.GenesisMetadata{}, cmd)
}
clientMetadata[i] = cmd
}
genMetadata = append(genMetadata, types.NewIdentifiedGenesisMetadata(
ic.ClientId,
clientMetadata,
))
}
return genMetadata, nil
}
// SetAllClientMetadata takes a list of IdentifiedGenesisMetadata and stores all of the metadata in the client store at the appropriate paths.
func (k Keeper) SetAllClientMetadata(ctx sdk.Context, genMetadata []types.IdentifiedGenesisMetadata) {
for _, igm := range genMetadata {
// create client store
store := k.ClientStore(ctx, igm.ClientId)
// set all metadata kv pairs in client store
for _, md := range igm.ClientMetadata {
store.Set(md.GetKey(), md.GetValue())
}
}
}
// GetAllConsensusStates returns all stored client consensus states. // GetAllConsensusStates returns all stored client consensus states.
func (k Keeper) GetAllConsensusStates(ctx sdk.Context) types.ClientsConsensusStates { func (k Keeper) GetAllConsensusStates(ctx sdk.Context) types.ClientsConsensusStates {
clientConsStates := make(types.ClientsConsensusStates, 0) clientConsStates := make(types.ClientsConsensusStates, 0)

View File

@ -258,6 +258,37 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() {
suite.Require().Equal(expGenClients.Sort(), genClients) suite.Require().Equal(expGenClients.Sort(), genClients)
} }
func (suite KeeperTestSuite) TestGetAllGenesisMetadata() {
expectedGenMetadata := []types.IdentifiedGenesisMetadata{
types.NewIdentifiedGenesisMetadata(
"clientA",
[]types.GenesisMetadata{
types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(0, 1)), []byte("foo")),
types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(0, 2)), []byte("bar")),
types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(0, 3)), []byte("baz")),
},
),
types.NewIdentifiedGenesisMetadata(
"clientB",
[]types.GenesisMetadata{
types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(1, 100)), []byte("val1")),
types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(2, 300)), []byte("val2")),
},
),
}
genClients := []types.IdentifiedClientState{
types.NewIdentifiedClientState("clientA", &ibctmtypes.ClientState{}), types.NewIdentifiedClientState("clientB", &ibctmtypes.ClientState{}),
types.NewIdentifiedClientState("clientC", &ibctmtypes.ClientState{}), types.NewIdentifiedClientState("clientD", &localhosttypes.ClientState{}),
}
suite.chainA.App.IBCKeeper.ClientKeeper.SetAllClientMetadata(suite.chainA.GetContext(), expectedGenMetadata)
actualGenMetadata, err := suite.chainA.App.IBCKeeper.ClientKeeper.GetAllClientMetadata(suite.chainA.GetContext(), genClients)
suite.Require().NoError(err, "get client metadata returned error unexpectedly")
suite.Require().Equal(expectedGenMetadata, actualGenMetadata, "retrieved metadata is unexpected")
}
func (suite KeeperTestSuite) TestGetConsensusState() { func (suite KeeperTestSuite) TestGetConsensusState() {
suite.ctx = suite.ctx.WithBlockHeight(10) suite.ctx = suite.ctx.WithBlockHeight(10)
cases := []struct { cases := []struct {

View File

@ -10,23 +10,24 @@ var (
ErrInvalidClient = sdkerrors.Register(SubModuleName, 3, "light client is invalid") ErrInvalidClient = sdkerrors.Register(SubModuleName, 3, "light client is invalid")
ErrClientNotFound = sdkerrors.Register(SubModuleName, 4, "light client not found") ErrClientNotFound = sdkerrors.Register(SubModuleName, 4, "light client not found")
ErrClientFrozen = sdkerrors.Register(SubModuleName, 5, "light client is frozen due to misbehaviour") ErrClientFrozen = sdkerrors.Register(SubModuleName, 5, "light client is frozen due to misbehaviour")
ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 6, "consensus state not found") ErrInvalidClientMetadata = sdkerrors.Register(SubModuleName, 6, "invalid client metadata")
ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 7, "invalid consensus state") ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 7, "consensus state not found")
ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 8, "client type not found") ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 8, "invalid consensus state")
ErrInvalidClientType = sdkerrors.Register(SubModuleName, 9, "invalid client type") ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 9, "client type not found")
ErrRootNotFound = sdkerrors.Register(SubModuleName, 10, "commitment root not found") ErrInvalidClientType = sdkerrors.Register(SubModuleName, 10, "invalid client type")
ErrInvalidHeader = sdkerrors.Register(SubModuleName, 11, "invalid client header") ErrRootNotFound = sdkerrors.Register(SubModuleName, 11, "commitment root not found")
ErrInvalidMisbehaviour = sdkerrors.Register(SubModuleName, 12, "invalid light client misbehaviour") ErrInvalidHeader = sdkerrors.Register(SubModuleName, 12, "invalid client header")
ErrFailedClientStateVerification = sdkerrors.Register(SubModuleName, 13, "client state verification failed") ErrInvalidMisbehaviour = sdkerrors.Register(SubModuleName, 13, "invalid light client misbehaviour")
ErrFailedClientConsensusStateVerification = sdkerrors.Register(SubModuleName, 14, "client consensus state verification failed") ErrFailedClientStateVerification = sdkerrors.Register(SubModuleName, 14, "client state verification failed")
ErrFailedConnectionStateVerification = sdkerrors.Register(SubModuleName, 15, "connection state verification failed") ErrFailedClientConsensusStateVerification = sdkerrors.Register(SubModuleName, 15, "client consensus state verification failed")
ErrFailedChannelStateVerification = sdkerrors.Register(SubModuleName, 16, "channel state verification failed") ErrFailedConnectionStateVerification = sdkerrors.Register(SubModuleName, 16, "connection state verification failed")
ErrFailedPacketCommitmentVerification = sdkerrors.Register(SubModuleName, 17, "packet commitment verification failed") ErrFailedChannelStateVerification = sdkerrors.Register(SubModuleName, 17, "channel state verification failed")
ErrFailedPacketAckVerification = sdkerrors.Register(SubModuleName, 18, "packet acknowledgement verification failed") ErrFailedPacketCommitmentVerification = sdkerrors.Register(SubModuleName, 18, "packet commitment verification failed")
ErrFailedPacketReceiptVerification = sdkerrors.Register(SubModuleName, 19, "packet receipt verification failed") ErrFailedPacketAckVerification = sdkerrors.Register(SubModuleName, 19, "packet acknowledgement verification failed")
ErrFailedNextSeqRecvVerification = sdkerrors.Register(SubModuleName, 20, "next sequence receive verification failed") ErrFailedPacketReceiptVerification = sdkerrors.Register(SubModuleName, 20, "packet receipt verification failed")
ErrSelfConsensusStateNotFound = sdkerrors.Register(SubModuleName, 21, "self consensus state not found") ErrFailedNextSeqRecvVerification = sdkerrors.Register(SubModuleName, 21, "next sequence receive verification failed")
ErrUpdateClientFailed = sdkerrors.Register(SubModuleName, 22, "unable to update light client") ErrSelfConsensusStateNotFound = sdkerrors.Register(SubModuleName, 22, "self consensus state not found")
ErrInvalidUpdateClientProposal = sdkerrors.Register(SubModuleName, 23, "invalid update client proposal") ErrUpdateClientFailed = sdkerrors.Register(SubModuleName, 23, "unable to update light client")
ErrInvalidUpgradeClient = sdkerrors.Register(SubModuleName, 24, "invalid client upgrade") ErrInvalidUpdateClientProposal = sdkerrors.Register(SubModuleName, 24, "invalid update client proposal")
ErrInvalidUpgradeClient = sdkerrors.Register(SubModuleName, 25, "invalid client upgrade")
) )

View File

@ -16,7 +16,10 @@ var (
_ codectypes.UnpackInterfacesMessage = GenesisState{} _ codectypes.UnpackInterfacesMessage = GenesisState{}
) )
var _ sort.Interface = ClientsConsensusStates{} var (
_ sort.Interface = ClientsConsensusStates{}
_ exported.GenesisMetadata = GenesisMetadata{}
)
// ClientsConsensusStates defines a slice of ClientConsensusStates that supports the sort interface // ClientsConsensusStates defines a slice of ClientConsensusStates that supports the sort interface
type ClientsConsensusStates []ClientConsensusStates type ClientsConsensusStates []ClientConsensusStates
@ -66,12 +69,13 @@ func (ccs ClientConsensusStates) UnpackInterfaces(unpacker codectypes.AnyUnpacke
// NewGenesisState creates a GenesisState instance. // NewGenesisState creates a GenesisState instance.
func NewGenesisState( func NewGenesisState(
clients []IdentifiedClientState, clientsConsensus ClientsConsensusStates, clients []IdentifiedClientState, clientsConsensus ClientsConsensusStates, clientsMetadata []IdentifiedGenesisMetadata,
params Params, createLocalhost bool, nextClientSequence uint64, params Params, createLocalhost bool, nextClientSequence uint64,
) GenesisState { ) GenesisState {
return GenesisState{ return GenesisState{
Clients: clients, Clients: clients,
ClientsConsensus: clientsConsensus, ClientsConsensus: clientsConsensus,
ClientsMetadata: clientsMetadata,
Params: params, Params: params,
CreateLocalhost: createLocalhost, CreateLocalhost: createLocalhost,
NextClientSequence: nextClientSequence, NextClientSequence: nextClientSequence,
@ -151,14 +155,14 @@ func (gs GenesisState) Validate() error {
validClients[client.ClientId] = clientState.ClientType() validClients[client.ClientId] = clientState.ClientType()
} }
for i, cc := range gs.ClientsConsensus { for _, cc := range gs.ClientsConsensus {
// check that consensus state is for a client in the genesis clients list // check that consensus state is for a client in the genesis clients list
clientType, ok := validClients[cc.ClientId] clientType, ok := validClients[cc.ClientId]
if !ok { if !ok {
return fmt.Errorf("consensus state in genesis has a client id %s that does not map to a genesis client", cc.ClientId) return fmt.Errorf("consensus state in genesis has a client id %s that does not map to a genesis client", cc.ClientId)
} }
for _, consensusState := range cc.ConsensusStates { for i, consensusState := range cc.ConsensusStates {
if consensusState.Height.IsZero() { if consensusState.Height.IsZero() {
return fmt.Errorf("consensus state height cannot be zero") return fmt.Errorf("consensus state height cannot be zero")
} }
@ -169,7 +173,7 @@ func (gs GenesisState) Validate() error {
} }
if err := cs.ValidateBasic(); err != nil { if err := cs.ValidateBasic(); err != nil {
return fmt.Errorf("invalid client consensus state %v index %d: %w", cs, i, err) return fmt.Errorf("invalid client consensus state %v clientID %s index %d: %w", cs, cc.ClientId, i, err)
} }
// ensure consensus state type matches client state type // ensure consensus state type matches client state type
@ -178,6 +182,21 @@ func (gs GenesisState) Validate() error {
} }
} }
}
for _, clientMetadata := range gs.ClientsMetadata {
// check that metadata is for a client in the genesis clients list
_, ok := validClients[clientMetadata.ClientId]
if !ok {
return fmt.Errorf("metadata in genesis has a client id %s that does not map to a genesis client", clientMetadata.ClientId)
}
for i, gm := range clientMetadata.ClientMetadata {
if err := gm.Validate(); err != nil {
return fmt.Errorf("invalid client metadata %v clientID %s index %d: %w", gm, clientMetadata.ClientId, i, err)
}
}
} }
@ -191,3 +210,41 @@ func (gs GenesisState) Validate() error {
return nil return nil
} }
// NewGenesisMetadata is a constructor for GenesisMetadata
func NewGenesisMetadata(key, val []byte) GenesisMetadata {
return GenesisMetadata{
Key: key,
Value: val,
}
}
// GetKey returns the key of metadata. Implements exported.GenesisMetadata interface.
func (gm GenesisMetadata) GetKey() []byte {
return gm.Key
}
// GetValue returns the value of metadata. Implements exported.GenesisMetadata interface.
func (gm GenesisMetadata) GetValue() []byte {
return gm.Value
}
// Validate ensures key and value of metadata are not empty
func (gm GenesisMetadata) Validate() error {
if len(gm.Key) == 0 {
return fmt.Errorf("genesis metadata key cannot be empty")
}
if len(gm.Value) == 0 {
return fmt.Errorf("genesis metadata value cannot be empty")
}
return nil
}
// NewIdentifiedGenesisMetadata takes in a client ID and list of genesis metadata for that client
// and constructs a new IdentifiedGenesisMetadata.
func NewIdentifiedGenesisMetadata(clientID string, gms []GenesisMetadata) IdentifiedGenesisMetadata {
return IdentifiedGenesisMetadata{
ClientId: clientID,
ClientMetadata: gms,
}
}

View File

@ -29,11 +29,13 @@ type GenesisState struct {
Clients IdentifiedClientStates `protobuf:"bytes,1,rep,name=clients,proto3,castrepeated=IdentifiedClientStates" json:"clients"` Clients IdentifiedClientStates `protobuf:"bytes,1,rep,name=clients,proto3,castrepeated=IdentifiedClientStates" json:"clients"`
// consensus states from each client // consensus states from each client
ClientsConsensus ClientsConsensusStates `protobuf:"bytes,2,rep,name=clients_consensus,json=clientsConsensus,proto3,castrepeated=ClientsConsensusStates" json:"clients_consensus" yaml:"clients_consensus"` ClientsConsensus ClientsConsensusStates `protobuf:"bytes,2,rep,name=clients_consensus,json=clientsConsensus,proto3,castrepeated=ClientsConsensusStates" json:"clients_consensus" yaml:"clients_consensus"`
Params Params `protobuf:"bytes,3,opt,name=params,proto3" json:"params"` // metadata from each client
ClientsMetadata []IdentifiedGenesisMetadata `protobuf:"bytes,3,rep,name=clients_metadata,json=clientsMetadata,proto3" json:"clients_metadata" yaml:"clients_metadata"`
Params Params `protobuf:"bytes,4,opt,name=params,proto3" json:"params"`
// create localhost on initialization // create localhost on initialization
CreateLocalhost bool `protobuf:"varint,4,opt,name=create_localhost,json=createLocalhost,proto3" json:"create_localhost,omitempty" yaml:"create_localhost"` CreateLocalhost bool `protobuf:"varint,5,opt,name=create_localhost,json=createLocalhost,proto3" json:"create_localhost,omitempty" yaml:"create_localhost"`
// the sequence for the next generated client identifier // the sequence for the next generated client identifier
NextClientSequence uint64 `protobuf:"varint,5,opt,name=next_client_sequence,json=nextClientSequence,proto3" json:"next_client_sequence,omitempty" yaml:"next_client_sequence"` NextClientSequence uint64 `protobuf:"varint,6,opt,name=next_client_sequence,json=nextClientSequence,proto3" json:"next_client_sequence,omitempty" yaml:"next_client_sequence"`
} }
func (m *GenesisState) Reset() { *m = GenesisState{} } func (m *GenesisState) Reset() { *m = GenesisState{} }
@ -83,6 +85,13 @@ func (m *GenesisState) GetClientsConsensus() ClientsConsensusStates {
return nil return nil
} }
func (m *GenesisState) GetClientsMetadata() []IdentifiedGenesisMetadata {
if m != nil {
return m.ClientsMetadata
}
return nil
}
func (m *GenesisState) GetParams() Params { func (m *GenesisState) GetParams() Params {
if m != nil { if m != nil {
return m.Params return m.Params
@ -104,39 +113,145 @@ func (m *GenesisState) GetNextClientSequence() uint64 {
return 0 return 0
} }
// GenesisMetadata defines the genesis type for metadata that clients may return
// with ExportMetadata
type GenesisMetadata struct {
// store key of metadata without clientID-prefix
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
// metadata value
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (m *GenesisMetadata) Reset() { *m = GenesisMetadata{} }
func (m *GenesisMetadata) String() string { return proto.CompactTextString(m) }
func (*GenesisMetadata) ProtoMessage() {}
func (*GenesisMetadata) Descriptor() ([]byte, []int) {
return fileDescriptor_bcd0c0f1f2e6a91a, []int{1}
}
func (m *GenesisMetadata) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisMetadata.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 *GenesisMetadata) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisMetadata.Merge(m, src)
}
func (m *GenesisMetadata) XXX_Size() int {
return m.Size()
}
func (m *GenesisMetadata) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisMetadata.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisMetadata proto.InternalMessageInfo
// IdentifiedGenesisMetadata has the client metadata with the corresponding client id.
type IdentifiedGenesisMetadata struct {
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"`
ClientMetadata []GenesisMetadata `protobuf:"bytes,2,rep,name=client_metadata,json=clientMetadata,proto3" json:"client_metadata" yaml:"client_metadata"`
}
func (m *IdentifiedGenesisMetadata) Reset() { *m = IdentifiedGenesisMetadata{} }
func (m *IdentifiedGenesisMetadata) String() string { return proto.CompactTextString(m) }
func (*IdentifiedGenesisMetadata) ProtoMessage() {}
func (*IdentifiedGenesisMetadata) Descriptor() ([]byte, []int) {
return fileDescriptor_bcd0c0f1f2e6a91a, []int{2}
}
func (m *IdentifiedGenesisMetadata) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *IdentifiedGenesisMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_IdentifiedGenesisMetadata.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 *IdentifiedGenesisMetadata) XXX_Merge(src proto.Message) {
xxx_messageInfo_IdentifiedGenesisMetadata.Merge(m, src)
}
func (m *IdentifiedGenesisMetadata) XXX_Size() int {
return m.Size()
}
func (m *IdentifiedGenesisMetadata) XXX_DiscardUnknown() {
xxx_messageInfo_IdentifiedGenesisMetadata.DiscardUnknown(m)
}
var xxx_messageInfo_IdentifiedGenesisMetadata proto.InternalMessageInfo
func (m *IdentifiedGenesisMetadata) GetClientId() string {
if m != nil {
return m.ClientId
}
return ""
}
func (m *IdentifiedGenesisMetadata) GetClientMetadata() []GenesisMetadata {
if m != nil {
return m.ClientMetadata
}
return nil
}
func init() { func init() {
proto.RegisterType((*GenesisState)(nil), "ibc.core.client.v1.GenesisState") proto.RegisterType((*GenesisState)(nil), "ibc.core.client.v1.GenesisState")
proto.RegisterType((*GenesisMetadata)(nil), "ibc.core.client.v1.GenesisMetadata")
proto.RegisterType((*IdentifiedGenesisMetadata)(nil), "ibc.core.client.v1.IdentifiedGenesisMetadata")
} }
func init() { proto.RegisterFile("ibc/core/client/v1/genesis.proto", fileDescriptor_bcd0c0f1f2e6a91a) } func init() { proto.RegisterFile("ibc/core/client/v1/genesis.proto", fileDescriptor_bcd0c0f1f2e6a91a) }
var fileDescriptor_bcd0c0f1f2e6a91a = []byte{ var fileDescriptor_bcd0c0f1f2e6a91a = []byte{
// 400 bytes of a gzipped FileDescriptorProto // 535 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x8e, 0x9a, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0x4d, 0x6e, 0xd3, 0x40,
0x1c, 0xc6, 0x99, 0x6a, 0x6d, 0x83, 0x4d, 0x6a, 0x27, 0xa6, 0x25, 0x9a, 0x00, 0xe1, 0x44, 0x0f, 0x14, 0xce, 0x34, 0x69, 0x68, 0xa7, 0x15, 0x0d, 0xa3, 0xa8, 0x98, 0x54, 0xb2, 0x2d, 0xb3, 0x09,
0x32, 0xd5, 0x1e, 0xda, 0x78, 0xc4, 0xa4, 0x4d, 0x93, 0x1e, 0x2a, 0xbd, 0xf5, 0x42, 0x60, 0x9c, 0x8b, 0xd8, 0x24, 0x2c, 0x40, 0xd9, 0x20, 0xb9, 0x12, 0xa8, 0x12, 0x48, 0xd4, 0xec, 0xd8, 0x58,
0x22, 0x29, 0x30, 0x96, 0x19, 0x8d, 0xbe, 0xc5, 0x66, 0x1f, 0x63, 0x9f, 0xc4, 0xa3, 0xc7, 0xbd, 0x93, 0xf1, 0x90, 0x5a, 0x75, 0x3c, 0x21, 0x33, 0x89, 0x9a, 0x1b, 0xb0, 0x44, 0x9c, 0x80, 0x35,
0x2c, 0xbb, 0xd1, 0x37, 0xf0, 0x09, 0x36, 0x30, 0xe3, 0x1e, 0x94, 0x3d, 0xf1, 0xcf, 0x37, 0xbf, 0x67, 0xe0, 0x00, 0x5d, 0x76, 0xd9, 0x55, 0x40, 0xc9, 0x0d, 0x72, 0x02, 0xe4, 0x99, 0x71, 0x7f,
0xef, 0xfb, 0xfe, 0x21, 0x7f, 0xd5, 0x8c, 0x43, 0x8c, 0x30, 0xcd, 0x09, 0xc2, 0x49, 0x4c, 0x32, 0x5c, 0xb7, 0xab, 0xbc, 0x7c, 0xf3, 0x7d, 0xdf, 0x7b, 0xfa, 0x9e, 0x1f, 0xb4, 0xe3, 0x01, 0xf1,
0x8e, 0x56, 0x43, 0x14, 0x91, 0x8c, 0xb0, 0x98, 0x39, 0x8b, 0x9c, 0x72, 0x0a, 0x61, 0x1c, 0x62, 0x08, 0x9b, 0x50, 0x8f, 0x24, 0x31, 0x4d, 0x85, 0x37, 0xeb, 0x7a, 0x43, 0x9a, 0x52, 0x1e, 0x73,
0xa7, 0x24, 0x1c, 0x41, 0x38, 0xab, 0x61, 0xcf, 0xa8, 0x71, 0xc9, 0xd7, 0xca, 0xd4, 0xeb, 0x46, 0x77, 0x3c, 0x61, 0x82, 0x21, 0x14, 0x0f, 0x88, 0x9b, 0x31, 0x5c, 0xc5, 0x70, 0x67, 0xdd, 0x96,
0x34, 0xa2, 0xd5, 0x88, 0xca, 0x49, 0xa8, 0xd6, 0x5d, 0x43, 0x7d, 0xf3, 0x5d, 0x84, 0xff, 0xe6, 0x55, 0xa2, 0xd2, 0xaf, 0x52, 0xd4, 0x6a, 0x0e, 0xd9, 0x90, 0xc9, 0xd2, 0xcb, 0x2a, 0x85, 0x3a,
0x01, 0x27, 0x10, 0xab, 0xaf, 0x84, 0x8d, 0x69, 0xc0, 0x6c, 0xd8, 0xed, 0xd1, 0x47, 0xe7, 0xb2, 0x97, 0x35, 0xb8, 0xfb, 0x5e, 0x99, 0x7f, 0x16, 0x58, 0x50, 0x44, 0xe0, 0x23, 0x25, 0xe3, 0x06,
0xcd, 0xf9, 0x31, 0x23, 0x19, 0x8f, 0xff, 0xc6, 0x64, 0x36, 0xa9, 0xb4, 0xca, 0xeb, 0xea, 0xdb, 0xb0, 0xab, 0xed, 0x9d, 0xde, 0x0b, 0xf7, 0x6e, 0x37, 0xf7, 0x28, 0xa2, 0xa9, 0x88, 0xbf, 0xc6,
0xc2, 0x50, 0x6e, 0xee, 0x8d, 0xf7, 0xb5, 0xcf, 0xcc, 0x3b, 0x25, 0xc3, 0x6b, 0xa0, 0xbe, 0x93, 0x34, 0x3a, 0x94, 0x98, 0xd4, 0xfa, 0xe6, 0xf9, 0xc2, 0xaa, 0xfc, 0xfe, 0x6b, 0xed, 0x97, 0x3e,
0xb3, 0x8f, 0x69, 0xc6, 0x48, 0xc6, 0x96, 0x4c, 0x7b, 0xf1, 0x7c, 0x9f, 0x88, 0x99, 0x9c, 0x50, 0xf3, 0x20, 0x77, 0x46, 0x3f, 0x01, 0x7c, 0xa2, 0xeb, 0x90, 0xb0, 0x94, 0xd3, 0x94, 0x4f, 0xb9,
0x91, 0xe7, 0x8e, 0xcb, 0xbe, 0x63, 0x61, 0x68, 0x9b, 0x20, 0x4d, 0xc6, 0xd6, 0x45, 0xa2, 0x55, 0xb1, 0x71, 0x7f, 0x3f, 0x65, 0x73, 0x98, 0x53, 0x95, 0x9f, 0xdf, 0xcf, 0xfa, 0xad, 0x17, 0x96,
0xee, 0x22, 0xac, 0xec, 0xcc, 0xeb, 0x75, 0xf0, 0x99, 0x0e, 0xbf, 0xaa, 0xad, 0x45, 0x90, 0x07, 0x31, 0xc7, 0xa3, 0xa4, 0xef, 0xdc, 0x71, 0x74, 0xb2, 0x59, 0x94, 0x94, 0x17, 0xb4, 0x41, 0x83,
0x29, 0xd3, 0x1a, 0x26, 0xb0, 0xdb, 0xa3, 0x5e, 0xdd, 0x22, 0xbf, 0x2a, 0xc2, 0x6d, 0x96, 0xcd, 0x14, 0x70, 0x34, 0x87, 0x39, 0x16, 0x8e, 0xa8, 0xc0, 0x11, 0x16, 0xd8, 0xa8, 0xca, 0x91, 0x3a,
0x9e, 0xe4, 0xe1, 0x37, 0xb5, 0x83, 0x73, 0x12, 0x70, 0xe2, 0x27, 0x14, 0x07, 0xc9, 0x9c, 0x32, 0x0f, 0x47, 0xa0, 0xf3, 0xfb, 0xa8, 0x45, 0xbe, 0xa5, 0xc7, 0x7a, 0x7a, 0x7b, 0xac, 0xdc, 0xd4,
0xae, 0x35, 0x4d, 0x60, 0xbf, 0x76, 0xfb, 0xc7, 0xc2, 0xf8, 0x20, 0xb7, 0x3b, 0x23, 0x2c, 0xef, 0x09, 0xf6, 0x34, 0x94, 0x2b, 0xd0, 0x1b, 0x58, 0x1f, 0xe3, 0x09, 0x1e, 0x71, 0xa3, 0x66, 0x83,
0xad, 0x90, 0x7e, 0x9e, 0x14, 0x38, 0x55, 0xbb, 0x19, 0x59, 0x73, 0x5f, 0xd4, 0xf9, 0x8c, 0xfc, 0xf6, 0x4e, 0xaf, 0x55, 0xd6, 0xf0, 0x93, 0x64, 0xf8, 0xb5, 0xcc, 0x3d, 0xd0, 0x7c, 0xf4, 0x0e,
0x5f, 0x92, 0x0c, 0x13, 0xed, 0xa5, 0x09, 0xec, 0xa6, 0x6b, 0x1c, 0x0b, 0xa3, 0x2f, 0xb2, 0xea, 0x36, 0xc8, 0x84, 0x62, 0x41, 0xc3, 0x84, 0x11, 0x9c, 0x9c, 0x30, 0x2e, 0x8c, 0x4d, 0x1b, 0xb4,
0x28, 0xcb, 0x83, 0xa5, 0x2c, 0x7f, 0xb8, 0x14, 0xdd, 0xe9, 0x76, 0xaf, 0x83, 0xdd, 0x5e, 0x07, 0xb7, 0xfc, 0x83, 0x1b, 0x13, 0x14, 0x18, 0xd9, 0x04, 0x12, 0xfa, 0x90, 0x23, 0xe8, 0x18, 0x36,
0x0f, 0x7b, 0x1d, 0x5c, 0x1d, 0x74, 0x65, 0x77, 0xd0, 0x95, 0xdb, 0x83, 0xae, 0xfc, 0xf9, 0x12, 0x53, 0x7a, 0x26, 0x42, 0xd5, 0x2e, 0xe4, 0xf4, 0xdb, 0x94, 0xa6, 0x84, 0x1a, 0x75, 0x1b, 0xb4,
0xc5, 0x7c, 0xbe, 0x0c, 0x1d, 0x4c, 0x53, 0x84, 0x29, 0x4b, 0x29, 0x93, 0x9f, 0x01, 0x9b, 0xfd, 0x6b, 0xbe, 0xb5, 0x5e, 0x58, 0x07, 0xca, 0xab, 0x8c, 0xe5, 0x04, 0x28, 0x83, 0xf5, 0xae, 0x73,
0x43, 0x6b, 0xf4, 0x74, 0x4f, 0x9f, 0x46, 0x03, 0x79, 0x52, 0x7c, 0xb3, 0x20, 0x2c, 0x6c, 0x55, 0xf0, 0x2d, 0xdc, 0x2b, 0x24, 0x83, 0x1a, 0xb0, 0x7a, 0x4a, 0xe7, 0x06, 0xb0, 0x41, 0x7b, 0x37,
0x97, 0xf3, 0xf9, 0x31, 0x00, 0x00, 0xff, 0xff, 0x7c, 0xcd, 0xe7, 0x85, 0xa8, 0x02, 0x00, 0x00, 0xc8, 0x4a, 0xd4, 0x84, 0x9b, 0x33, 0x9c, 0x4c, 0xa9, 0xb1, 0x21, 0x31, 0xf5, 0xa7, 0x5f, 0xfb,
0xfe, 0xcb, 0xaa, 0x38, 0x7f, 0x00, 0x7c, 0x76, 0x6f, 0xca, 0xa8, 0x0b, 0xb7, 0xf5, 0x18, 0x71,
0x24, 0x1d, 0xb7, 0xfd, 0xe6, 0x7a, 0x61, 0x35, 0x6e, 0x86, 0x1e, 0xc6, 0x91, 0x13, 0x6c, 0xa9,
0xfa, 0x28, 0x42, 0x09, 0xd4, 0xc9, 0x5f, 0x2f, 0x58, 0x7d, 0x73, 0xcf, 0xcb, 0xf2, 0x2e, 0xae,
0xd5, 0xd4, 0x6b, 0xdd, 0xbf, 0xd5, 0xe1, 0x7a, 0xab, 0x8f, 0x15, 0x72, 0xc5, 0x3f, 0x3e, 0x5f,
0x9a, 0xe0, 0x62, 0x69, 0x82, 0x7f, 0x4b, 0x13, 0xfc, 0x58, 0x99, 0x95, 0x8b, 0x95, 0x59, 0xb9,
0x5c, 0x99, 0x95, 0x2f, 0xaf, 0x87, 0xb1, 0x38, 0x99, 0x0e, 0x5c, 0xc2, 0x46, 0x1e, 0x61, 0x7c,
0xc4, 0xb8, 0xfe, 0xe9, 0xf0, 0xe8, 0xd4, 0x3b, 0xf3, 0xae, 0x4e, 0xf9, 0x65, 0xaf, 0xa3, 0xaf,
0x59, 0xcc, 0xc7, 0x94, 0x0f, 0xea, 0xf2, 0x68, 0x5f, 0xfd, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x61,
0x6f, 0x94, 0xed, 0x23, 0x04, 0x00, 0x00,
} }
func (m *GenesisState) Marshal() (dAtA []byte, err error) { func (m *GenesisState) Marshal() (dAtA []byte, err error) {
@ -162,7 +277,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
if m.NextClientSequence != 0 { if m.NextClientSequence != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.NextClientSequence)) i = encodeVarintGenesis(dAtA, i, uint64(m.NextClientSequence))
i-- i--
dAtA[i] = 0x28 dAtA[i] = 0x30
} }
if m.CreateLocalhost { if m.CreateLocalhost {
i-- i--
@ -172,7 +287,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0 dAtA[i] = 0
} }
i-- i--
dAtA[i] = 0x20 dAtA[i] = 0x28
} }
{ {
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
@ -183,7 +298,21 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintGenesis(dAtA, i, uint64(size)) i = encodeVarintGenesis(dAtA, i, uint64(size))
} }
i-- i--
dAtA[i] = 0x22
if len(m.ClientsMetadata) > 0 {
for iNdEx := len(m.ClientsMetadata) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.ClientsMetadata[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a dAtA[i] = 0x1a
}
}
if len(m.ClientsConsensus) > 0 { if len(m.ClientsConsensus) > 0 {
for iNdEx := len(m.ClientsConsensus) - 1; iNdEx >= 0; iNdEx-- { for iNdEx := len(m.ClientsConsensus) - 1; iNdEx >= 0; iNdEx-- {
{ {
@ -215,6 +344,87 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *GenesisMetadata) 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 *GenesisMetadata) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Value) > 0 {
i -= len(m.Value)
copy(dAtA[i:], m.Value)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Value)))
i--
dAtA[i] = 0x12
}
if len(m.Key) > 0 {
i -= len(m.Key)
copy(dAtA[i:], m.Key)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Key)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *IdentifiedGenesisMetadata) 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 *IdentifiedGenesisMetadata) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *IdentifiedGenesisMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.ClientMetadata) > 0 {
for iNdEx := len(m.ClientMetadata) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.ClientMetadata[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
}
if len(m.ClientId) > 0 {
i -= len(m.ClientId)
copy(dAtA[i:], m.ClientId)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.ClientId)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v) offset -= sovGenesis(v)
base := offset base := offset
@ -244,6 +454,12 @@ func (m *GenesisState) Size() (n int) {
n += 1 + l + sovGenesis(uint64(l)) n += 1 + l + sovGenesis(uint64(l))
} }
} }
if len(m.ClientsMetadata) > 0 {
for _, e := range m.ClientsMetadata {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
l = m.Params.Size() l = m.Params.Size()
n += 1 + l + sovGenesis(uint64(l)) n += 1 + l + sovGenesis(uint64(l))
if m.CreateLocalhost { if m.CreateLocalhost {
@ -255,6 +471,42 @@ func (m *GenesisState) Size() (n int) {
return n return n
} }
func (m *GenesisMetadata) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Key)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
l = len(m.Value)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
return n
}
func (m *IdentifiedGenesisMetadata) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.ClientId)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
if len(m.ClientMetadata) > 0 {
for _, e := range m.ClientMetadata {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
return n
}
func sovGenesis(x uint64) (n int) { func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7 return (math_bits.Len64(x|1) + 6) / 7
} }
@ -359,6 +611,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
case 3: case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClientsMetadata", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ClientsMetadata = append(m.ClientsMetadata, IdentifiedGenesisMetadata{})
if err := m.ClientsMetadata[len(m.ClientsMetadata)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
} }
@ -391,7 +677,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 4: case 5:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CreateLocalhost", wireType) return fmt.Errorf("proto: wrong wireType = %d for field CreateLocalhost", wireType)
} }
@ -411,7 +697,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
} }
} }
m.CreateLocalhost = bool(v != 0) m.CreateLocalhost = bool(v != 0)
case 5: case 6:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NextClientSequence", wireType) return fmt.Errorf("proto: wrong wireType = %d for field NextClientSequence", wireType)
} }
@ -454,6 +740,246 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *GenesisMetadata) 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 ErrIntOverflowGenesis
}
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: GenesisMetadata: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisMetadata: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...)
if m.Key == nil {
m.Key = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
if m.Value == nil {
m.Value = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *IdentifiedGenesisMetadata) 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 ErrIntOverflowGenesis
}
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: IdentifiedGenesisMetadata: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: IdentifiedGenesisMetadata: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ClientId = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClientMetadata", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ClientMetadata = append(m.ClientMetadata, GenesisMetadata{})
if err := m.ClientMetadata[len(m.ClientMetadata)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) { func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0

View File

@ -91,6 +91,15 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
[]types.IdentifiedGenesisMetadata{
types.NewIdentifiedGenesisMetadata(
clientID,
[]types.GenesisMetadata{
types.NewGenesisMetadata([]byte("key1"), []byte("val1")),
types.NewGenesisMetadata([]byte("key2"), []byte("val2")),
},
),
},
types.NewParams(exported.Tendermint, exported.Localhost), types.NewParams(exported.Tendermint, exported.Localhost),
false, false,
2, 2,
@ -121,6 +130,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint), types.NewParams(exported.Tendermint),
false, false,
0, 0,
@ -137,6 +147,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
types.NewIdentifiedClientState(exported.Localhost, localhosttypes.NewClientState("chaindID", types.ZeroHeight())), types.NewIdentifiedClientState(exported.Localhost, localhosttypes.NewClientState("chaindID", types.ZeroHeight())),
}, },
nil, nil,
nil,
types.NewParams(exported.Tendermint), types.NewParams(exported.Tendermint),
false, false,
0, 0,
@ -159,7 +170,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
tmClientID1, tmClientID1,
[]types.ConsensusStateWithHeight{ []types.ConsensusStateWithHeight{
types.NewConsensusStateWithHeight( types.NewConsensusStateWithHeight(
types.ZeroHeight(), types.NewHeight(0, 1),
ibctmtypes.NewConsensusState( ibctmtypes.NewConsensusState(
header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash,
), ),
@ -167,6 +178,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint), types.NewParams(exported.Tendermint),
false, false,
0, 0,
@ -197,6 +209,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint), types.NewParams(exported.Tendermint),
false, false,
0, 0,
@ -227,6 +240,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint), types.NewParams(exported.Tendermint),
false, false,
0, 0,
@ -257,12 +271,87 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Solomachine), types.NewParams(exported.Solomachine),
false, false,
0, 0,
), ),
expPass: false, expPass: false,
}, },
{
name: "metadata client-id does not match a genesis client",
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false),
),
types.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight),
),
},
[]types.ClientConsensusStates{
types.NewClientConsensusStates(
clientID,
[]types.ConsensusStateWithHeight{
types.NewConsensusStateWithHeight(
header.GetHeight().(types.Height),
ibctmtypes.NewConsensusState(
header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash,
),
),
},
),
},
[]types.IdentifiedGenesisMetadata{
types.NewIdentifiedGenesisMetadata(
"wrongclientid",
[]types.GenesisMetadata{
types.NewGenesisMetadata([]byte("key1"), []byte("val1")),
types.NewGenesisMetadata([]byte("key2"), []byte("val2")),
},
),
},
types.NewParams(exported.Tendermint, exported.Localhost),
false,
0,
),
expPass: false,
},
{
name: "invalid metadata",
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false),
),
},
[]types.ClientConsensusStates{
types.NewClientConsensusStates(
clientID,
[]types.ConsensusStateWithHeight{
types.NewConsensusStateWithHeight(
header.GetHeight().(types.Height),
ibctmtypes.NewConsensusState(
header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash,
),
),
},
),
},
[]types.IdentifiedGenesisMetadata{
types.NewIdentifiedGenesisMetadata(
clientID,
[]types.GenesisMetadata{
types.NewGenesisMetadata([]byte(""), []byte("val1")),
types.NewGenesisMetadata([]byte("key2"), []byte("val2")),
},
),
},
types.NewParams(exported.Tendermint),
false,
0,
),
},
{ {
name: "invalid params", name: "invalid params",
genState: types.NewGenesisState( genState: types.NewGenesisState(
@ -287,6 +376,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(" "), types.NewParams(" "),
false, false,
0, 0,
@ -317,6 +407,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(" "), types.NewParams(" "),
true, true,
0, 0,
@ -347,6 +438,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint), types.NewParams(exported.Tendermint),
true, true,
2, 2,
@ -377,6 +469,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint, exported.Localhost), types.NewParams(exported.Tendermint, exported.Localhost),
false, false,
0, 0,
@ -407,6 +500,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint, exported.Localhost), types.NewParams(exported.Tendermint, exported.Localhost),
false, false,
5, 5,
@ -434,6 +528,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
nil,
types.NewParams(exported.Tendermint, exported.Localhost), types.NewParams(exported.Tendermint, exported.Localhost),
false, false,
5, 5,

View File

@ -22,6 +22,7 @@ import (
const ( const (
flagVersionIdentifier = "version-identifier" flagVersionIdentifier = "version-identifier"
flagVersionFeatures = "version-features" flagVersionFeatures = "version-features"
flagDelayPeriod = "delay-period"
) )
// NewConnectionOpenInitCmd defines the command to initialize a connection on // NewConnectionOpenInitCmd defines the command to initialize a connection on
@ -34,7 +35,7 @@ func NewConnectionOpenInitCmd() *cobra.Command {
- 'version-identifier' flag can be a single pre-selected version identifier to be used in the handshake. - 'version-identifier' flag can be a single pre-selected version identifier to be used in the handshake.
- 'version-features' flag can be a list of features separated by commas to accompany the version identifier.`, - 'version-features' flag can be a list of features separated by commas to accompany the version identifier.`,
Example: fmt.Sprintf( Example: fmt.Sprintf(
"%s tx %s %s open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", "%s tx %s %s open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\" --delay-period=500",
version.AppName, host.ModuleName, types.SubModuleName, version.AppName, host.ModuleName, types.SubModuleName,
), ),
Args: cobra.ExactArgs(3), Args: cobra.ExactArgs(3),
@ -67,9 +68,14 @@ func NewConnectionOpenInitCmd() *cobra.Command {
version = types.NewVersion(versionIdentifier, features) version = types.NewVersion(versionIdentifier, features)
} }
delayPeriod, err := cmd.Flags().GetUint64(flagDelayPeriod)
if err != nil {
return err
}
msg := types.NewMsgConnectionOpenInit( msg := types.NewMsgConnectionOpenInit(
clientID, counterpartyClientID, clientID, counterpartyClientID,
counterpartyPrefix, version, clientCtx.GetFromAddress(), counterpartyPrefix, version, delayPeriod, clientCtx.GetFromAddress(),
) )
if err := msg.ValidateBasic(); err != nil { if err := msg.ValidateBasic(); err != nil {
@ -84,6 +90,7 @@ func NewConnectionOpenInitCmd() *cobra.Command {
// at this step in the handshake. // at this step in the handshake.
cmd.Flags().String(flagVersionIdentifier, "", "version identifier to be used in the connection handshake version negotiation") cmd.Flags().String(flagVersionIdentifier, "", "version identifier to be used in the connection handshake version negotiation")
cmd.Flags().String(flagVersionFeatures, "", "version features list separated by commas without spaces. The features must function with the version identifier.") cmd.Flags().String(flagVersionFeatures, "", "version features list separated by commas without spaces. The features must function with the version identifier.")
cmd.Flags().Uint64(flagDelayPeriod, 0, "delay period that must pass before packet verification can pass against a consensus state")
flags.AddTxFlagsToCmd(cmd) flags.AddTxFlagsToCmd(cmd)
return cmd return cmd
@ -174,9 +181,14 @@ func NewConnectionOpenTryCmd() *cobra.Command {
return err return err
} }
delayPeriod, err := cmd.Flags().GetUint64(flagDelayPeriod)
if err != nil {
return err
}
msg := types.NewMsgConnectionOpenTry( msg := types.NewMsgConnectionOpenTry(
connectionID, clientID, counterpartyConnectionID, counterpartyClientID, connectionID, clientID, counterpartyConnectionID, counterpartyClientID,
counterpartyClient, counterpartyPrefix, counterpartyVersions, counterpartyClient, counterpartyPrefix, counterpartyVersions, delayPeriod,
proofInit, proofClient, proofConsensus, proofHeight, proofInit, proofClient, proofConsensus, proofHeight,
consensusHeight, clientCtx.GetFromAddress(), consensusHeight, clientCtx.GetFromAddress(),
) )
@ -189,6 +201,7 @@ func NewConnectionOpenTryCmd() *cobra.Command {
}, },
} }
cmd.Flags().Uint64(flagDelayPeriod, 0, "delay period that must pass before packet verification can pass against a consensus state")
flags.AddTxFlagsToCmd(cmd) flags.AddTxFlagsToCmd(cmd)
return cmd return cmd

View File

@ -10,7 +10,7 @@ import (
// state. // state.
func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
for _, connection := range gs.Connections { for _, connection := range gs.Connections {
conn := types.NewConnectionEnd(connection.State, connection.ClientId, connection.Counterparty, connection.Versions) conn := types.NewConnectionEnd(connection.State, connection.ClientId, connection.Counterparty, connection.Versions, connection.DelayPeriod)
k.SetConnection(ctx, connection.Id, conn) k.SetConnection(ctx, connection.Id, conn)
} }
for _, connPaths := range gs.ClientConnectionPaths { for _, connPaths := range gs.ClientConnectionPaths {

View File

@ -52,7 +52,7 @@ func (suite *KeeperTestSuite) TestQueryConnection() {
connB := suite.chainB.GetFirstTestConnection(clientB, clientA) connB := suite.chainB.GetFirstTestConnection(clientB, clientA)
counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix()) counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix())
expConnection = types.NewConnectionEnd(types.INIT, clientA, counterparty, types.ExportedVersionsToProto(types.GetCompatibleVersions())) expConnection = types.NewConnectionEnd(types.INIT, clientA, counterparty, types.ExportedVersionsToProto(types.GetCompatibleVersions()), 500)
suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, expConnection) suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, expConnection)
req = &types.QueryConnectionRequest{ req = &types.QueryConnectionRequest{
@ -121,9 +121,9 @@ func (suite *KeeperTestSuite) TestQueryConnections() {
// counterparty connection id is blank after open init // counterparty connection id is blank after open init
counterparty3 := types.NewCounterparty(clientB, "", suite.chainB.GetPrefix()) counterparty3 := types.NewCounterparty(clientB, "", suite.chainB.GetPrefix())
conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterparty1, types.ExportedVersionsToProto(types.GetCompatibleVersions())) conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterparty1, types.ExportedVersionsToProto(types.GetCompatibleVersions()), 0)
conn2 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) conn2 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions()), 0)
conn3 := types.NewConnectionEnd(types.INIT, clientA, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) conn3 := types.NewConnectionEnd(types.INIT, clientA, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions()), 0)
iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1) iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1)
iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2) iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2)

View File

@ -24,6 +24,7 @@ func (k Keeper) ConnOpenInit(
clientID string, clientID string,
counterparty types.Counterparty, // counterpartyPrefix, counterpartyClientIdentifier counterparty types.Counterparty, // counterpartyPrefix, counterpartyClientIdentifier
version *types.Version, version *types.Version,
delayPeriod uint64,
) (string, error) { ) (string, error) {
versions := types.GetCompatibleVersions() versions := types.GetCompatibleVersions()
if version != nil { if version != nil {
@ -36,7 +37,7 @@ func (k Keeper) ConnOpenInit(
// connection defines chain A's ConnectionEnd // connection defines chain A's ConnectionEnd
connectionID := k.GenerateConnectionIdentifier(ctx) connectionID := k.GenerateConnectionIdentifier(ctx)
connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions)) connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions), delayPeriod)
k.SetConnection(ctx, connectionID, connection) k.SetConnection(ctx, connectionID, connection)
if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil {
@ -62,6 +63,7 @@ func (k Keeper) ConnOpenTry(
ctx sdk.Context, ctx sdk.Context,
previousConnectionID string, // previousIdentifier previousConnectionID string, // previousIdentifier
counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier
delayPeriod uint64,
clientID string, // clientID of chainA clientID string, // clientID of chainA
clientState exported.ClientState, // clientState that chainA has for chainB clientState exported.ClientState, // clientState that chainA has for chainB
counterpartyVersions []exported.Version, // supported versions of chain A counterpartyVersions []exported.Version, // supported versions of chain A
@ -89,10 +91,12 @@ func (k Keeper) ConnOpenTry(
// counterparty is chainA and connection is on INIT stage. // counterparty is chainA and connection is on INIT stage.
// Check that existing connection versions for initialized connection is equal to compatible // Check that existing connection versions for initialized connection is equal to compatible
// versions for this chain. // versions for this chain.
// ensure that existing connection's delay period is the same as desired delay period.
if !(previousConnection.Counterparty.ConnectionId == "" && if !(previousConnection.Counterparty.ConnectionId == "" &&
bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) &&
previousConnection.ClientId == clientID && previousConnection.ClientId == clientID &&
previousConnection.Counterparty.ClientId == counterparty.ClientId) { previousConnection.Counterparty.ClientId == counterparty.ClientId &&
previousConnection.DelayPeriod == delayPeriod) {
return "", sdkerrors.Wrap(types.ErrInvalidConnection, "connection fields mismatch previous connection fields") return "", sdkerrors.Wrap(types.ErrInvalidConnection, "connection fields mismatch previous connection fields")
} }
@ -128,9 +132,10 @@ func (k Keeper) ConnOpenTry(
// expectedConnection defines Chain A's ConnectionEnd // expectedConnection defines Chain A's ConnectionEnd
// NOTE: chain A's counterparty is chain B (i.e where this code is executed) // NOTE: chain A's counterparty is chain B (i.e where this code is executed)
// NOTE: chainA and chainB must have the same delay period
prefix := k.GetCommitmentPrefix() prefix := k.GetCommitmentPrefix()
expectedCounterparty := types.NewCounterparty(clientID, "", commitmenttypes.NewMerklePrefix(prefix.Bytes())) expectedCounterparty := types.NewCounterparty(clientID, "", commitmenttypes.NewMerklePrefix(prefix.Bytes()))
expectedConnection := types.NewConnectionEnd(types.INIT, counterparty.ClientId, expectedCounterparty, types.ExportedVersionsToProto(counterpartyVersions)) expectedConnection := types.NewConnectionEnd(types.INIT, counterparty.ClientId, expectedCounterparty, types.ExportedVersionsToProto(counterpartyVersions), delayPeriod)
supportedVersions := types.GetCompatibleVersions() supportedVersions := types.GetCompatibleVersions()
if len(previousConnection.Versions) != 0 { if len(previousConnection.Versions) != 0 {
@ -146,7 +151,7 @@ func (k Keeper) ConnOpenTry(
} }
// connection defines chain B's ConnectionEnd // connection defines chain B's ConnectionEnd
connection := types.NewConnectionEnd(types.TRYOPEN, clientID, counterparty, []*types.Version{version}) connection := types.NewConnectionEnd(types.TRYOPEN, clientID, counterparty, []*types.Version{version}, delayPeriod)
// Check that ChainA committed expectedConnectionEnd to its state // Check that ChainA committed expectedConnectionEnd to its state
if err := k.VerifyConnectionState( if err := k.VerifyConnectionState(
@ -252,7 +257,7 @@ func (k Keeper) ConnOpenAck(
prefix := k.GetCommitmentPrefix() prefix := k.GetCommitmentPrefix()
expectedCounterparty := types.NewCounterparty(connection.ClientId, connectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes())) expectedCounterparty := types.NewCounterparty(connection.ClientId, connectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes()))
expectedConnection := types.NewConnectionEnd(types.TRYOPEN, connection.Counterparty.ClientId, expectedCounterparty, []*types.Version{version}) expectedConnection := types.NewConnectionEnd(types.TRYOPEN, connection.Counterparty.ClientId, expectedCounterparty, []*types.Version{version}, connection.DelayPeriod)
// Ensure that ChainB stored expected connectionEnd in its state during ConnOpenTry // Ensure that ChainB stored expected connectionEnd in its state during ConnOpenTry
if err := k.VerifyConnectionState( if err := k.VerifyConnectionState(
@ -314,7 +319,7 @@ func (k Keeper) ConnOpenConfirm(
prefix := k.GetCommitmentPrefix() prefix := k.GetCommitmentPrefix()
expectedCounterparty := types.NewCounterparty(connection.ClientId, connectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes())) expectedCounterparty := types.NewCounterparty(connection.ClientId, connectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes()))
expectedConnection := types.NewConnectionEnd(types.OPEN, connection.Counterparty.ClientId, expectedCounterparty, connection.Versions) expectedConnection := types.NewConnectionEnd(types.OPEN, connection.Counterparty.ClientId, expectedCounterparty, connection.Versions, connection.DelayPeriod)
// Check that connection on ChainA is open // Check that connection on ChainA is open
if err := k.VerifyConnectionState( if err := k.VerifyConnectionState(

View File

@ -17,6 +17,7 @@ func (suite *KeeperTestSuite) TestConnOpenInit() {
clientA string clientA string
clientB string clientB string
version *types.Version version *types.Version
delayPeriod uint64
emptyConnBID bool emptyConnBID bool
) )
@ -36,6 +37,11 @@ func (suite *KeeperTestSuite) TestConnOpenInit() {
clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint)
version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0]
}, true}, }, true},
{"success with non zero delayPeriod", func() {
clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint)
delayPeriod = uint64(time.Hour.Nanoseconds())
}, true},
{"invalid version", func() { {"invalid version", func() {
clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint)
version = &types.Version{} version = &types.Version{}
@ -62,7 +68,7 @@ func (suite *KeeperTestSuite) TestConnOpenInit() {
} }
counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix()) counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix())
connectionID, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), clientA, counterparty, version) connectionID, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), clientA, counterparty, version, delayPeriod)
if tc.expPass { if tc.expPass {
suite.Require().NoError(err) suite.Require().NoError(err)
@ -81,6 +87,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
var ( var (
clientA string clientA string
clientB string clientB string
delayPeriod uint64
previousConnectionID string previousConnectionID string
versions []exported.Version versions []exported.Version
consensusHeight exported.Height consensusHeight exported.Height
@ -110,6 +117,25 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
previousConnectionID = connB.ID previousConnectionID = connB.ID
}, true}, }, true},
{"success with delay period", func() {
clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint)
connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB)
suite.Require().NoError(err)
delayPeriod = uint64(time.Hour.Nanoseconds())
// set delay period on counterparty to non-zero value
conn := suite.chainA.GetConnection(connA)
conn.DelayPeriod = delayPeriod
suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, conn)
// commit in order for proof to return correct value
suite.coordinator.CommitBlock(suite.chainA)
suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint)
// retrieve client state of chainA to pass as counterpartyClient
counterpartyClient = suite.chainA.GetClientState(clientA)
}, true},
{"invalid counterparty client", func() { {"invalid counterparty client", func() {
clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint)
_, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) _, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB)
@ -283,7 +309,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
proofClient, _ := suite.chainA.QueryProof(clientKey) proofClient, _ := suite.chainA.QueryProof(clientKey)
connectionID, err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( connectionID, err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry(
suite.chainB.GetContext(), previousConnectionID, counterparty, clientB, counterpartyClient, suite.chainB.GetContext(), previousConnectionID, counterparty, delayPeriod, clientB, counterpartyClient,
versions, proofInit, proofClient, proofConsensus, versions, proofInit, proofClient, proofConsensus,
proofHeight, consensusHeight, proofHeight, consensusHeight,
) )

View File

@ -62,8 +62,8 @@ func (suite KeeperTestSuite) TestGetAllConnections() {
counterpartyB0 := types.NewCounterparty(clientB, connB0.ID, suite.chainB.GetPrefix()) // connection B0 counterpartyB0 := types.NewCounterparty(clientB, connB0.ID, suite.chainB.GetPrefix()) // connection B0
counterpartyB1 := types.NewCounterparty(clientB, connB1.ID, suite.chainB.GetPrefix()) // connection B1 counterpartyB1 := types.NewCounterparty(clientB, connB1.ID, suite.chainB.GetPrefix()) // connection B1
conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterpartyB0, types.ExportedVersionsToProto(types.GetCompatibleVersions())) // A0 - B0 conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterpartyB0, types.ExportedVersionsToProto(types.GetCompatibleVersions()), 0) // A0 - B0
conn2 := types.NewConnectionEnd(types.OPEN, clientA, counterpartyB1, types.ExportedVersionsToProto(types.GetCompatibleVersions())) // A1 - B1 conn2 := types.NewConnectionEnd(types.OPEN, clientA, counterpartyB1, types.ExportedVersionsToProto(types.GetCompatibleVersions()), 0) // A1 - B1
iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1) iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1)
iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2) iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2)

View File

@ -128,6 +128,7 @@ func (k Keeper) VerifyPacketCommitment(
if err := clientState.VerifyPacketCommitment( if err := clientState.VerifyPacketCommitment(
k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height, k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height,
uint64(ctx.BlockTime().UnixNano()), connection.GetDelayPeriod(),
connection.GetCounterparty().GetPrefix(), proof, portID, channelID, connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
sequence, commitmentBytes, sequence, commitmentBytes,
); err != nil { ); err != nil {
@ -156,6 +157,7 @@ func (k Keeper) VerifyPacketAcknowledgement(
if err := clientState.VerifyPacketAcknowledgement( if err := clientState.VerifyPacketAcknowledgement(
k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height, k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height,
uint64(ctx.BlockTime().UnixNano()), connection.GetDelayPeriod(),
connection.GetCounterparty().GetPrefix(), proof, portID, channelID, connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
sequence, acknowledgement, sequence, acknowledgement,
); err != nil { ); err != nil {
@ -184,6 +186,7 @@ func (k Keeper) VerifyPacketReceiptAbsence(
if err := clientState.VerifyPacketReceiptAbsence( if err := clientState.VerifyPacketReceiptAbsence(
k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height, k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height,
uint64(ctx.BlockTime().UnixNano()), connection.GetDelayPeriod(),
connection.GetCounterparty().GetPrefix(), proof, portID, channelID, connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
sequence, sequence,
); err != nil { ); err != nil {
@ -211,6 +214,7 @@ func (k Keeper) VerifyNextSequenceRecv(
if err := clientState.VerifyNextSequenceRecv( if err := clientState.VerifyNextSequenceRecv(
k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height, k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height,
uint64(ctx.BlockTime().UnixNano()), connection.GetDelayPeriod(),
connection.GetCounterparty().GetPrefix(), proof, portID, channelID, connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
nextSequenceRecv, nextSequenceRecv,
); err != nil { ); err != nil {

View File

@ -258,12 +258,15 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() {
changeClientID bool changeClientID bool
changePacketCommitmentState bool changePacketCommitmentState bool
heightDiff uint64 heightDiff uint64
delayPeriod uint64
expPass bool expPass bool
}{ }{
{"verification success", false, false, 0, true}, {"verification success", false, false, 0, 0, true},
{"client state not found- changed client ID", true, false, 0, false}, {"verification success: delay period passed", false, false, 0, uint64(1 * time.Second.Nanoseconds()), true},
{"consensus state not found - increased proof height", false, false, 5, false}, {"delay period has not passed", false, false, 0, uint64(1 * time.Hour.Nanoseconds()), false},
{"verification failed - changed packet commitment state", false, true, 0, false}, {"client state not found- changed client ID", true, false, 0, 0, false},
{"consensus state not found - increased proof height", false, false, 5, 0, false},
{"verification failed - changed packet commitment state", false, true, 0, 0, false},
} }
for _, tc := range cases { for _, tc := range cases {
@ -273,7 +276,9 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() {
suite.SetupTest() // reset suite.SetupTest() // reset
_, clientB, _, connB, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED) _, clientB, _, connB, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED)
connection := suite.chainB.GetConnection(connB) connection := suite.chainB.GetConnection(connB)
connection.DelayPeriod = tc.delayPeriod
if tc.changeClientID { if tc.changeClientID {
connection.ClientId = ibctesting.InvalidID connection.ClientId = ibctesting.InvalidID
} }
@ -313,12 +318,15 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() {
changeClientID bool changeClientID bool
changeAcknowledgement bool changeAcknowledgement bool
heightDiff uint64 heightDiff uint64
delayPeriod uint64
expPass bool expPass bool
}{ }{
{"verification success", false, false, 0, true}, {"verification success", false, false, 0, 0, true},
{"client state not found- changed client ID", true, false, 0, false}, {"verification success: delay period passed", false, false, 0, uint64(1 * time.Second.Nanoseconds()), true},
{"consensus state not found - increased proof height", false, false, 5, false}, {"delay period has not passed", false, false, 0, uint64(1 * time.Hour.Nanoseconds()), false},
{"verification failed - changed acknowledgement", false, true, 0, false}, {"client state not found- changed client ID", true, false, 0, 0, false},
{"consensus state not found - increased proof height", false, false, 5, 0, false},
{"verification failed - changed acknowledgement", false, true, 0, 0, false},
} }
for _, tc := range cases { for _, tc := range cases {
@ -328,7 +336,9 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() {
suite.SetupTest() // reset suite.SetupTest() // reset
clientA, clientB, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED) clientA, clientB, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED)
connection := suite.chainA.GetConnection(connA) connection := suite.chainA.GetConnection(connA)
connection.DelayPeriod = tc.delayPeriod
if tc.changeClientID { if tc.changeClientID {
connection.ClientId = ibctesting.InvalidID connection.ClientId = ibctesting.InvalidID
} }
@ -338,6 +348,10 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() {
err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB)
suite.Require().NoError(err) suite.Require().NoError(err)
// increment receiving chain's (chainB) time by 2 hour to always pass receive
suite.coordinator.IncrementTimeBy(time.Hour * 2)
suite.coordinator.CommitBlock(suite.chainB)
err = suite.coordinator.RecvPacket(suite.chainA, suite.chainB, clientA, packet) err = suite.coordinator.RecvPacket(suite.chainA, suite.chainB, clientA, packet)
suite.Require().NoError(err) suite.Require().NoError(err)
@ -372,12 +386,15 @@ func (suite *KeeperTestSuite) TestVerifyPacketReceiptAbsence() {
changeClientID bool changeClientID bool
recvAck bool recvAck bool
heightDiff uint64 heightDiff uint64
delayPeriod uint64
expPass bool expPass bool
}{ }{
{"verification success", false, false, 0, true}, {"verification success", false, false, 0, 0, true},
{"client state not found - changed client ID", true, false, 0, false}, {"verification success: delay period passed", false, false, 0, uint64(1 * time.Second.Nanoseconds()), true},
{"consensus state not found - increased proof height", false, false, 5, false}, {"delay period has not passed", false, false, 0, uint64(1 * time.Hour.Nanoseconds()), false},
{"verification failed - acknowledgement was received", false, true, 0, false}, {"client state not found - changed client ID", true, false, 0, 0, false},
{"consensus state not found - increased proof height", false, false, 5, 0, false},
{"verification failed - acknowledgement was received", false, true, 0, 0, false},
} }
for _, tc := range cases { for _, tc := range cases {
@ -387,7 +404,9 @@ func (suite *KeeperTestSuite) TestVerifyPacketReceiptAbsence() {
suite.SetupTest() // reset suite.SetupTest() // reset
clientA, clientB, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED) clientA, clientB, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED)
connection := suite.chainA.GetConnection(connA) connection := suite.chainA.GetConnection(connA)
connection.DelayPeriod = tc.delayPeriod
if tc.changeClientID { if tc.changeClientID {
connection.ClientId = ibctesting.InvalidID connection.ClientId = ibctesting.InvalidID
} }
@ -398,6 +417,10 @@ func (suite *KeeperTestSuite) TestVerifyPacketReceiptAbsence() {
suite.Require().NoError(err) suite.Require().NoError(err)
if tc.recvAck { if tc.recvAck {
// increment receiving chain's (chainB) time by 2 hour to always pass receive
suite.coordinator.IncrementTimeBy(time.Hour * 2)
suite.coordinator.CommitBlock(suite.chainB)
err = suite.coordinator.RecvPacket(suite.chainA, suite.chainB, clientA, packet) err = suite.coordinator.RecvPacket(suite.chainA, suite.chainB, clientA, packet)
suite.Require().NoError(err) suite.Require().NoError(err)
} else { } else {
@ -432,12 +455,15 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() {
changeClientID bool changeClientID bool
offsetSeq uint64 offsetSeq uint64
heightDiff uint64 heightDiff uint64
delayPeriod uint64
expPass bool expPass bool
}{ }{
{"verification success", false, 0, 0, true}, {"verification success", false, 0, 0, 0, true},
{"client state not found- changed client ID", true, 0, 0, false}, {"verification success: delay period passed", false, 0, 0, uint64(1 * time.Second.Nanoseconds()), true},
{"consensus state not found - increased proof height", false, 0, 5, false}, {"delay period has not passed", false, 0, 0, uint64(1 * time.Hour.Nanoseconds()), false},
{"verification failed - wrong expected next seq recv", false, 1, 0, false}, {"client state not found- changed client ID", true, 0, 0, 0, false},
{"consensus state not found - increased proof height", false, 0, 5, 0, false},
{"verification failed - wrong expected next seq recv", false, 1, 0, 0, false},
} }
for _, tc := range cases { for _, tc := range cases {
@ -447,7 +473,9 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() {
suite.SetupTest() // reset suite.SetupTest() // reset
clientA, clientB, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED) clientA, clientB, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, channeltypes.UNORDERED)
connection := suite.chainA.GetConnection(connA) connection := suite.chainA.GetConnection(connA)
connection.DelayPeriod = tc.delayPeriod
if tc.changeClientID { if tc.changeClientID {
connection.ClientId = ibctesting.InvalidID connection.ClientId = ibctesting.InvalidID
} }
@ -457,6 +485,10 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() {
err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB)
suite.Require().NoError(err) suite.Require().NoError(err)
// increment receiving chain's (chainB) time by 2 hour to always pass receive
suite.coordinator.IncrementTimeBy(time.Hour * 2)
suite.coordinator.CommitBlock(suite.chainB)
err = suite.coordinator.RecvPacket(suite.chainA, suite.chainB, clientA, packet) err = suite.coordinator.RecvPacket(suite.chainA, suite.chainB, clientA, packet)
suite.Require().NoError(err) suite.Require().NoError(err)

View File

@ -10,12 +10,13 @@ import (
var _ exported.ConnectionI = (*ConnectionEnd)(nil) var _ exported.ConnectionI = (*ConnectionEnd)(nil)
// NewConnectionEnd creates a new ConnectionEnd instance. // NewConnectionEnd creates a new ConnectionEnd instance.
func NewConnectionEnd(state State, clientID string, counterparty Counterparty, versions []*Version) ConnectionEnd { func NewConnectionEnd(state State, clientID string, counterparty Counterparty, versions []*Version, delayPeriod uint64) ConnectionEnd {
return ConnectionEnd{ return ConnectionEnd{
ClientId: clientID, ClientId: clientID,
Versions: versions, Versions: versions,
State: state, State: state,
Counterparty: counterparty, Counterparty: counterparty,
DelayPeriod: delayPeriod,
} }
} }
@ -39,6 +40,11 @@ func (c ConnectionEnd) GetVersions() []exported.Version {
return ProtoVersionsToExported(c.Versions) return ProtoVersionsToExported(c.Versions)
} }
// GetDelayPeriod implements the Connection interface
func (c ConnectionEnd) GetDelayPeriod() uint64 {
return c.DelayPeriod
}
// ValidateBasic implements the Connection interface. // ValidateBasic implements the Connection interface.
// NOTE: the protocol supports that the connection and client IDs match the // NOTE: the protocol supports that the connection and client IDs match the
// counterparty's. // counterparty's.
@ -107,6 +113,7 @@ func NewIdentifiedConnection(connectionID string, conn ConnectionEnd) Identified
Versions: conn.Versions, Versions: conn.Versions,
State: conn.State, State: conn.State,
Counterparty: conn.Counterparty, Counterparty: conn.Counterparty,
DelayPeriod: conn.DelayPeriod,
} }
} }
@ -115,6 +122,6 @@ func (ic IdentifiedConnection) ValidateBasic() error {
if err := host.ConnectionIdentifierValidator(ic.Id); err != nil { if err := host.ConnectionIdentifierValidator(ic.Id); err != nil {
return sdkerrors.Wrap(err, "invalid connection ID") return sdkerrors.Wrap(err, "invalid connection ID")
} }
connection := NewConnectionEnd(ic.State, ic.ClientId, ic.Counterparty, ic.Versions) connection := NewConnectionEnd(ic.State, ic.ClientId, ic.Counterparty, ic.Versions, ic.DelayPeriod)
return connection.ValidateBasic() return connection.ValidateBasic()
} }

View File

@ -63,18 +63,22 @@ func (State) EnumDescriptor() ([]byte, []int) {
} }
// ConnectionEnd defines a stateful object on a chain connected to another // ConnectionEnd defines a stateful object on a chain connected to another
// separate one. NOTE: there must only be 2 defined ConnectionEnds to establish // separate one.
// NOTE: there must only be 2 defined ConnectionEnds to establish
// a connection between two chains. // a connection between two chains.
type ConnectionEnd struct { type ConnectionEnd struct {
// client associated with this connection. // client associated with this connection.
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"`
// IBC version which can be utilised to determine encodings or protocols for // IBC version which can be utilised to determine encodings or protocols for
// channels or packets utilising this connection // channels or packets utilising this connection.
Versions []*Version `protobuf:"bytes,2,rep,name=versions,proto3" json:"versions,omitempty"` Versions []*Version `protobuf:"bytes,2,rep,name=versions,proto3" json:"versions,omitempty"`
// current state of the connection end. // current state of the connection end.
State State `protobuf:"varint,3,opt,name=state,proto3,enum=ibc.core.connection.v1.State" json:"state,omitempty"` State State `protobuf:"varint,3,opt,name=state,proto3,enum=ibc.core.connection.v1.State" json:"state,omitempty"`
// counterparty chain associated with this connection. // counterparty chain associated with this connection.
Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"` Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"`
// delay period that must pass before a consensus state can be used for packet-verification
// NOTE: delay period logic is only implemented by some clients.
DelayPeriod uint64 `protobuf:"varint,5,opt,name=delay_period,json=delayPeriod,proto3" json:"delay_period,omitempty" yaml:"delay_period"`
} }
func (m *ConnectionEnd) Reset() { *m = ConnectionEnd{} } func (m *ConnectionEnd) Reset() { *m = ConnectionEnd{} }
@ -124,6 +128,8 @@ type IdentifiedConnection struct {
State State `protobuf:"varint,4,opt,name=state,proto3,enum=ibc.core.connection.v1.State" json:"state,omitempty"` State State `protobuf:"varint,4,opt,name=state,proto3,enum=ibc.core.connection.v1.State" json:"state,omitempty"`
// counterparty chain associated with this connection. // counterparty chain associated with this connection.
Counterparty Counterparty `protobuf:"bytes,5,opt,name=counterparty,proto3" json:"counterparty"` Counterparty Counterparty `protobuf:"bytes,5,opt,name=counterparty,proto3" json:"counterparty"`
// delay period associated with this connection.
DelayPeriod uint64 `protobuf:"varint,6,opt,name=delay_period,json=delayPeriod,proto3" json:"delay_period,omitempty" yaml:"delay_period"`
} }
func (m *IdentifiedConnection) Reset() { *m = IdentifiedConnection{} } func (m *IdentifiedConnection) Reset() { *m = IdentifiedConnection{} }
@ -167,7 +173,7 @@ type Counterparty struct {
// identifies the connection end on the counterparty chain associated with a // identifies the connection end on the counterparty chain associated with a
// given connection. // given connection.
ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"`
// commitment merkle prefix of the counterparty chain // commitment merkle prefix of the counterparty chain.
Prefix types.MerklePrefix `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix"` Prefix types.MerklePrefix `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix"`
} }
@ -362,46 +368,48 @@ func init() {
} }
var fileDescriptor_90572467c054e43a = []byte{ var fileDescriptor_90572467c054e43a = []byte{
// 617 bytes of a gzipped FileDescriptorProto // 654 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xc1, 0x6a, 0xdb, 0x4c, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x41, 0x6b, 0xdb, 0x4c,
0x10, 0x96, 0x64, 0x39, 0xb1, 0xd7, 0xf1, 0xff, 0xbb, 0x8b, 0x29, 0x42, 0x10, 0x49, 0xa8, 0x85, 0x14, 0x94, 0x64, 0x39, 0xb1, 0xd7, 0xf1, 0xf7, 0xb9, 0x5b, 0xd3, 0x0a, 0x41, 0x24, 0xa1, 0x16,
0x9a, 0x42, 0xa4, 0x3a, 0x81, 0x1e, 0x12, 0x7a, 0x88, 0x1d, 0x15, 0x44, 0x5b, 0xd7, 0x28, 0x4e, 0x6a, 0x0a, 0xb1, 0xea, 0x04, 0x7a, 0x48, 0xe8, 0x21, 0x76, 0x5c, 0x10, 0x6d, 0x5d, 0xa3, 0x38,
0xa1, 0xb9, 0x04, 0x5b, 0xda, 0x24, 0x4b, 0x62, 0xc9, 0x48, 0x6b, 0x13, 0xbf, 0x41, 0xf0, 0xa9, 0x85, 0xe6, 0x62, 0x6c, 0x69, 0x93, 0x2c, 0xb1, 0xb5, 0x42, 0xda, 0x98, 0xf8, 0x1f, 0x84, 0x9c,
0xd7, 0x1e, 0x0c, 0x85, 0xbe, 0x40, 0x1f, 0x23, 0xf4, 0x94, 0x63, 0x4f, 0xa6, 0xd8, 0x6f, 0xe0, 0x7a, 0xed, 0x21, 0x50, 0xe8, 0x7f, 0x29, 0xa1, 0xa7, 0x1c, 0x7b, 0x32, 0x25, 0xb9, 0xf6, 0xe4,
0x27, 0x28, 0xd2, 0xca, 0xb2, 0x12, 0x9a, 0x43, 0xdd, 0x9e, 0x34, 0xb3, 0xf3, 0x7d, 0x9f, 0x76, 0x5f, 0x50, 0xa4, 0x95, 0x65, 0x25, 0x34, 0x87, 0xa4, 0x3d, 0xf9, 0xcd, 0xbe, 0x99, 0xf1, 0xbe,
0xbe, 0x1d, 0x06, 0x3c, 0xc3, 0x1d, 0x5b, 0xb7, 0x3d, 0x1f, 0xe9, 0xb6, 0xe7, 0xba, 0xc8, 0x26, 0xf1, 0xf3, 0x82, 0x67, 0xb8, 0x6f, 0x1b, 0x36, 0xf1, 0x91, 0x61, 0x13, 0xd7, 0x45, 0x36, 0xc5,
0xd8, 0x73, 0xf5, 0x41, 0x35, 0x95, 0x69, 0x3d, 0xdf, 0x23, 0x1e, 0x7c, 0x8c, 0x3b, 0xb6, 0x16, 0xc4, 0x35, 0x46, 0xb5, 0x14, 0xaa, 0x7a, 0x3e, 0xa1, 0x04, 0x3e, 0xc2, 0x7d, 0xbb, 0x1a, 0x12,
0x02, 0xb5, 0x54, 0x69, 0x50, 0x15, 0xcb, 0x67, 0xde, 0x99, 0x17, 0x41, 0xf4, 0x30, 0xa2, 0x68, 0xab, 0xa9, 0xd6, 0xa8, 0x26, 0x97, 0xf7, 0xc9, 0x3e, 0x89, 0x28, 0x46, 0x58, 0x31, 0xb6, 0x9c,
0x31, 0x2d, 0xdb, 0xed, 0x62, 0xd2, 0x45, 0x2e, 0xa1, 0xb2, 0x8b, 0x8c, 0x02, 0xd5, 0x11, 0x07, 0xb6, 0x1d, 0x0e, 0x31, 0x1d, 0x22, 0x97, 0x32, 0xdb, 0x19, 0x62, 0x44, 0xfd, 0x9b, 0x00, 0x8a,
0x8a, 0xf5, 0x44, 0xd0, 0x70, 0x1d, 0x58, 0x05, 0x79, 0xfb, 0x12, 0x23, 0x97, 0x9c, 0x60, 0x47, 0x8d, 0xc4, 0xb0, 0xe9, 0x3a, 0xb0, 0x06, 0xf2, 0xf6, 0x00, 0x23, 0x97, 0x76, 0xb1, 0x23, 0xf1,
0x60, 0x15, 0xb6, 0x92, 0xaf, 0x95, 0xe7, 0x13, 0xb9, 0x34, 0x6c, 0x77, 0x2f, 0x77, 0xd5, 0xa4, 0x1a, 0x5f, 0xc9, 0xd7, 0xcb, 0xd3, 0x89, 0x5a, 0x1a, 0xf7, 0x86, 0x83, 0x75, 0x3d, 0x69, 0xe9,
0xa4, 0x5a, 0x39, 0x1a, 0x9b, 0x0e, 0xdc, 0x03, 0xb9, 0x01, 0xf2, 0x03, 0xec, 0xb9, 0x81, 0xc0, 0x56, 0x8e, 0xd5, 0xa6, 0x03, 0x37, 0x40, 0x6e, 0x84, 0xfc, 0x00, 0x13, 0x37, 0x90, 0x04, 0x2d,
0x29, 0x99, 0x4a, 0x61, 0x5b, 0xd6, 0x7e, 0x7f, 0x5d, 0xed, 0x03, 0xc5, 0x59, 0x09, 0x01, 0xee, 0x53, 0x29, 0xac, 0xaa, 0xd5, 0x3f, 0x5f, 0xb7, 0xfa, 0x81, 0xf1, 0xac, 0x44, 0x00, 0xd7, 0x40,
0x80, 0x6c, 0x40, 0xda, 0x04, 0x09, 0x19, 0x85, 0xad, 0xfc, 0xb7, 0xbd, 0xf9, 0x10, 0xf3, 0x30, 0x36, 0xa0, 0x3d, 0x8a, 0xa4, 0x8c, 0xc6, 0x57, 0xfe, 0x5b, 0x5d, 0xbe, 0x4d, 0xb9, 0x1d, 0x92,
0x04, 0x59, 0x14, 0x0b, 0x1b, 0x60, 0xc3, 0xf6, 0xfa, 0x2e, 0x41, 0x7e, 0xaf, 0xed, 0x93, 0xa1, 0x2c, 0xc6, 0x85, 0x2d, 0xb0, 0x64, 0x93, 0x23, 0x97, 0x22, 0xdf, 0xeb, 0xf9, 0x74, 0x2c, 0x89,
0xc0, 0x2b, 0x6c, 0xa5, 0xb0, 0xfd, 0xf4, 0x21, 0x6e, 0x3d, 0x85, 0xad, 0xf1, 0x37, 0x13, 0x99, 0x1a, 0x5f, 0x29, 0xac, 0x3e, 0xbd, 0x4d, 0xdb, 0x48, 0x71, 0xeb, 0xe2, 0xf9, 0x44, 0xe5, 0xac,
0xb1, 0xee, 0xf0, 0x77, 0xf9, 0xeb, 0x2f, 0x32, 0xa3, 0x7e, 0xe3, 0x40, 0xd9, 0x74, 0x90, 0x4b, 0x6b, 0x7a, 0xb8, 0x0e, 0x96, 0x1c, 0x34, 0xe8, 0x8d, 0xbb, 0x1e, 0xf2, 0x31, 0x71, 0xa4, 0xac,
0xf0, 0x29, 0x46, 0xce, 0xd2, 0x16, 0xb8, 0x09, 0xb8, 0xc4, 0x8c, 0xe2, 0x7c, 0x22, 0xe7, 0xa9, 0xc6, 0x57, 0xc4, 0xfa, 0xe3, 0xe9, 0x44, 0x7d, 0xc8, 0xe6, 0x4e, 0x77, 0x75, 0xab, 0x10, 0xc1,
0x19, 0xa1, 0x0b, 0x1c, 0xbe, 0x67, 0x19, 0xf7, 0xc7, 0x96, 0x65, 0x56, 0xb6, 0x8c, 0xff, 0x0b, 0x76, 0x84, 0xd6, 0xc5, 0x93, 0x2f, 0x2a, 0xa7, 0xff, 0x12, 0x40, 0xd9, 0x74, 0x90, 0x4b, 0xf1,
0xcb, 0xb2, 0xff, 0xc4, 0xb2, 0xef, 0x2c, 0xd8, 0x48, 0x43, 0x57, 0x19, 0x9f, 0x57, 0xa0, 0xb8, 0x1e, 0x46, 0xce, 0x3c, 0x52, 0xb8, 0x0c, 0x84, 0x24, 0xc8, 0xe2, 0x74, 0xa2, 0xe6, 0x99, 0x61,
0xfc, 0xf7, 0xd2, 0x42, 0x61, 0x3e, 0x91, 0xcb, 0x31, 0x2d, 0x5d, 0x56, 0xc3, 0x8b, 0x2c, 0x72, 0x98, 0xa0, 0x80, 0x6f, 0xc4, 0x2d, 0xdc, 0x39, 0xee, 0xcc, 0xbd, 0xe3, 0x16, 0xff, 0x22, 0xee,
0xd3, 0x81, 0x35, 0xb0, 0xd6, 0xf3, 0xd1, 0x29, 0xbe, 0x8a, 0x26, 0xe8, 0x5e, 0x4b, 0xc9, 0xb8, 0xec, 0x3f, 0x8e, 0x7b, 0xe1, 0xce, 0x71, 0x7f, 0xe7, 0xc1, 0x52, 0xfa, 0x6b, 0xee, 0xb3, 0xb6,
0x0f, 0xaa, 0xda, 0x3b, 0xe4, 0x5f, 0x5c, 0xa2, 0x66, 0x84, 0x8d, 0x5b, 0x8a, 0x99, 0x71, 0x33, 0xaf, 0x40, 0x71, 0x7e, 0xef, 0x79, 0xfc, 0xd2, 0x74, 0xa2, 0x96, 0x63, 0x59, 0xba, 0xad, 0x87,
0x4f, 0x40, 0xa1, 0x1e, 0x5d, 0xaa, 0xd9, 0x26, 0xe7, 0x01, 0x2c, 0x83, 0x6c, 0x2f, 0x0c, 0x04, 0x43, 0xcc, 0xb0, 0xe9, 0xc0, 0x3a, 0x58, 0xf0, 0x7c, 0xb4, 0x87, 0x8f, 0xa3, 0xcd, 0xbd, 0x11,
0x56, 0xc9, 0x54, 0xf2, 0x16, 0x4d, 0xd4, 0x63, 0xf0, 0xff, 0x72, 0x32, 0x28, 0x70, 0x85, 0x9e, 0x47, 0xf2, 0x37, 0x1b, 0xd5, 0xaa, 0xef, 0x90, 0x7f, 0x38, 0x40, 0xed, 0x88, 0x1b, 0xc7, 0x11,
0x13, 0x6d, 0x2e, 0xad, 0xfd, 0x06, 0xac, 0xc7, 0xaf, 0x0d, 0x25, 0x00, 0xf0, 0x62, 0x14, 0x7d, 0x2b, 0xe3, 0x61, 0x9e, 0x80, 0x42, 0x23, 0xba, 0x54, 0xbb, 0x47, 0x0f, 0x02, 0x58, 0x06, 0x59,
0x2a, 0x6a, 0xa5, 0x4e, 0xa0, 0x08, 0x72, 0xa7, 0xa8, 0x4d, 0xfa, 0x3e, 0x5a, 0x68, 0x24, 0x39, 0x2f, 0x2c, 0x24, 0x5e, 0xcb, 0x54, 0xf2, 0x16, 0x03, 0xfa, 0x2e, 0xf8, 0x7f, 0xbe, 0x55, 0x8c,
0xed, 0xe6, 0xf9, 0x67, 0x16, 0x64, 0xa3, 0x09, 0x80, 0x2f, 0x81, 0x7c, 0xd8, 0xda, 0x6f, 0x19, 0x78, 0x8f, 0x99, 0x13, 0x6f, 0x21, 0xed, 0xfd, 0x06, 0x2c, 0xc6, 0x9b, 0x02, 0x15, 0x00, 0xf0,
0x27, 0x47, 0x0d, 0xb3, 0x61, 0xb6, 0xcc, 0xfd, 0xb7, 0xe6, 0xb1, 0x71, 0x70, 0x72, 0xd4, 0x38, 0x6c, 0x8d, 0x7d, 0x66, 0x6a, 0xa5, 0x4e, 0xa0, 0x0c, 0x72, 0x7b, 0xa8, 0x47, 0x8f, 0x7c, 0x34,
0x6c, 0x1a, 0x75, 0xf3, 0xb5, 0x69, 0x1c, 0x94, 0x18, 0xf1, 0xd1, 0x68, 0xac, 0x14, 0xef, 0x00, 0xf3, 0x48, 0x30, 0x9b, 0xe6, 0xf9, 0x67, 0x1e, 0x64, 0xa3, 0xed, 0x81, 0x2f, 0x81, 0xba, 0xdd,
0xa0, 0x00, 0x00, 0xe5, 0x85, 0x87, 0x25, 0x56, 0xcc, 0x8d, 0xc6, 0x0a, 0x1f, 0xc6, 0x50, 0x02, 0xd9, 0xec, 0x34, 0xbb, 0x3b, 0x2d, 0xb3, 0x65, 0x76, 0xcc, 0xcd, 0xb7, 0xe6, 0x6e, 0x73, 0xab,
0x45, 0x5a, 0x69, 0x59, 0x1f, 0xdf, 0x37, 0x8d, 0x46, 0x89, 0x13, 0x0b, 0xa3, 0xb1, 0xb2, 0x1e, 0xbb, 0xd3, 0xda, 0x6e, 0x37, 0x1b, 0xe6, 0x6b, 0xb3, 0xb9, 0x55, 0xe2, 0xe4, 0x07, 0xa7, 0x67,
0xa7, 0x4b, 0x66, 0x54, 0xcc, 0x50, 0x66, 0x18, 0x8b, 0xfc, 0xf5, 0x57, 0x89, 0xa9, 0x1d, 0xdd, 0x5a, 0xf1, 0x1a, 0x01, 0x4a, 0x00, 0x30, 0x5d, 0x78, 0x58, 0xe2, 0xe5, 0xdc, 0xe9, 0x99, 0x26,
0x4c, 0x25, 0xf6, 0x76, 0x2a, 0xb1, 0x3f, 0xa7, 0x12, 0xfb, 0x69, 0x26, 0x31, 0xb7, 0x33, 0x89, 0x86, 0x35, 0x54, 0x40, 0x91, 0x75, 0x3a, 0xd6, 0xc7, 0xf7, 0xed, 0x66, 0xab, 0x24, 0xc8, 0x85,
0xf9, 0x31, 0x93, 0x98, 0xe3, 0xbd, 0x33, 0x4c, 0xce, 0xfb, 0x9d, 0xf0, 0xe9, 0x74, 0xdb, 0x0b, 0xd3, 0x33, 0x6d, 0x31, 0x86, 0x73, 0x65, 0xd4, 0xcc, 0x30, 0x65, 0x58, 0xcb, 0xe2, 0xc9, 0x57,
0xba, 0x5e, 0x10, 0x7f, 0xb6, 0x02, 0xe7, 0x42, 0xbf, 0xd2, 0x93, 0xc5, 0xf6, 0x62, 0x67, 0x2b, 0x85, 0xab, 0xef, 0x9c, 0x5f, 0x2a, 0xfc, 0xc5, 0xa5, 0xc2, 0xff, 0xbc, 0x54, 0xf8, 0x4f, 0x57,
0xb5, 0x32, 0xc9, 0xb0, 0x87, 0x82, 0xce, 0x5a, 0xb4, 0xd4, 0x76, 0x7e, 0x05, 0x00, 0x00, 0xff, 0x0a, 0x77, 0x71, 0xa5, 0x70, 0x3f, 0xae, 0x14, 0x6e, 0x77, 0x63, 0x1f, 0xd3, 0x83, 0xa3, 0x7e,
0xff, 0x6d, 0xfb, 0xee, 0xb6, 0x56, 0x05, 0x00, 0x00, 0xf8, 0xd3, 0x19, 0x36, 0x09, 0x86, 0x24, 0x88, 0x3f, 0x56, 0x02, 0xe7, 0xd0, 0x38, 0x36, 0x92,
0x07, 0xf5, 0xc5, 0xda, 0x4a, 0xea, 0xa9, 0xa6, 0x63, 0x0f, 0x05, 0xfd, 0x85, 0xe8, 0x31, 0x5d,
0xfb, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x48, 0x0f, 0xf2, 0xaa, 0xce, 0x05, 0x00, 0x00,
} }
func (m *ConnectionEnd) Marshal() (dAtA []byte, err error) { func (m *ConnectionEnd) Marshal() (dAtA []byte, err error) {
@ -424,6 +432,11 @@ func (m *ConnectionEnd) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.DelayPeriod != 0 {
i = encodeVarintConnection(dAtA, i, uint64(m.DelayPeriod))
i--
dAtA[i] = 0x28
}
{ {
size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i])
if err != nil { if err != nil {
@ -483,6 +496,11 @@ func (m *IdentifiedConnection) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.DelayPeriod != 0 {
i = encodeVarintConnection(dAtA, i, uint64(m.DelayPeriod))
i--
dAtA[i] = 0x30
}
{ {
size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i])
if err != nil { if err != nil {
@ -718,6 +736,9 @@ func (m *ConnectionEnd) Size() (n int) {
} }
l = m.Counterparty.Size() l = m.Counterparty.Size()
n += 1 + l + sovConnection(uint64(l)) n += 1 + l + sovConnection(uint64(l))
if m.DelayPeriod != 0 {
n += 1 + sovConnection(uint64(m.DelayPeriod))
}
return n return n
} }
@ -746,6 +767,9 @@ func (m *IdentifiedConnection) Size() (n int) {
} }
l = m.Counterparty.Size() l = m.Counterparty.Size()
n += 1 + l + sovConnection(uint64(l)) n += 1 + l + sovConnection(uint64(l))
if m.DelayPeriod != 0 {
n += 1 + sovConnection(uint64(m.DelayPeriod))
}
return n return n
} }
@ -974,6 +998,25 @@ func (m *ConnectionEnd) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DelayPeriod", wireType)
}
m.DelayPeriod = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConnection
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.DelayPeriod |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipConnection(dAtA[iNdEx:]) skippy, err := skipConnection(dAtA[iNdEx:])
@ -1177,6 +1220,25 @@ func (m *IdentifiedConnection) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DelayPeriod", wireType)
}
m.DelayPeriod = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConnection
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.DelayPeriod |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipConnection(dAtA[iNdEx:]) skippy, err := skipConnection(dAtA[iNdEx:])

View File

@ -29,27 +29,27 @@ func TestConnectionValidateBasic(t *testing.T) {
}{ }{
{ {
"valid connection", "valid connection",
types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}}, types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, 500},
true, true,
}, },
{ {
"invalid client id", "invalid client id",
types.ConnectionEnd{"(clientID1)", []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}}, types.ConnectionEnd{"(clientID1)", []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, 500},
false, false,
}, },
{ {
"empty versions", "empty versions",
types.ConnectionEnd{clientID, nil, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}}, types.ConnectionEnd{clientID, nil, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, 500},
false, false,
}, },
{ {
"invalid version", "invalid version",
types.ConnectionEnd{clientID, []*types.Version{{}}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}}, types.ConnectionEnd{clientID, []*types.Version{{}}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, 500},
false, false,
}, },
{ {
"invalid counterparty", "invalid counterparty",
types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, emptyPrefix}}, types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, emptyPrefix}, 500},
false, false,
}, },
} }
@ -98,12 +98,12 @@ func TestIdentifiedConnectionValidateBasic(t *testing.T) {
}{ }{
{ {
"valid connection", "valid connection",
types.NewIdentifiedConnection(clientID, types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}}), types.NewIdentifiedConnection(clientID, types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, 500}),
true, true,
}, },
{ {
"invalid connection id", "invalid connection id",
types.NewIdentifiedConnection("(connectionIDONE)", types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}}), types.NewIdentifiedConnection("(connectionIDONE)", types.ConnectionEnd{clientID, []*types.Version{ibctesting.ConnectionVersion}, types.INIT, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, 500}),
false, false,
}, },
} }

View File

@ -26,7 +26,7 @@ func TestValidateGenesis(t *testing.T) {
name: "valid genesis", name: "valid genesis",
genState: types.NewGenesisState( genState: types.NewGenesisState(
[]types.IdentifiedConnection{ []types.IdentifiedConnection{
types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion}, 500)),
}, },
[]types.ConnectionPaths{ []types.ConnectionPaths{
{clientID, []string{connectionID}}, {clientID, []string{connectionID}},
@ -39,7 +39,7 @@ func TestValidateGenesis(t *testing.T) {
name: "invalid connection", name: "invalid connection",
genState: types.NewGenesisState( genState: types.NewGenesisState(
[]types.IdentifiedConnection{ []types.IdentifiedConnection{
types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, "(CLIENTIDONE)", types.Counterparty{clientID, connectionID, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, "(CLIENTIDONE)", types.Counterparty{clientID, connectionID, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion}, 500)),
}, },
[]types.ConnectionPaths{ []types.ConnectionPaths{
{clientID, []string{connectionID}}, {clientID, []string{connectionID}},
@ -52,7 +52,7 @@ func TestValidateGenesis(t *testing.T) {
name: "invalid client id", name: "invalid client id",
genState: types.NewGenesisState( genState: types.NewGenesisState(
[]types.IdentifiedConnection{ []types.IdentifiedConnection{
types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion}, 500)),
}, },
[]types.ConnectionPaths{ []types.ConnectionPaths{
{"(CLIENTIDONE)", []string{connectionID}}, {"(CLIENTIDONE)", []string{connectionID}},
@ -65,7 +65,7 @@ func TestValidateGenesis(t *testing.T) {
name: "invalid path", name: "invalid path",
genState: types.NewGenesisState( genState: types.NewGenesisState(
[]types.IdentifiedConnection{ []types.IdentifiedConnection{
types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion}, 500)),
}, },
[]types.ConnectionPaths{ []types.ConnectionPaths{
{clientID, []string{invalidConnectionID}}, {clientID, []string{invalidConnectionID}},
@ -78,7 +78,7 @@ func TestValidateGenesis(t *testing.T) {
name: "invalid connection identifier", name: "invalid connection identifier",
genState: types.NewGenesisState( genState: types.NewGenesisState(
[]types.IdentifiedConnection{ []types.IdentifiedConnection{
types.NewIdentifiedConnection("conn-0", types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), types.NewIdentifiedConnection("conn-0", types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion}, 500)),
}, },
[]types.ConnectionPaths{ []types.ConnectionPaths{
{clientID, []string{connectionID}}, {clientID, []string{connectionID}},
@ -91,7 +91,7 @@ func TestValidateGenesis(t *testing.T) {
name: "next connection sequence is not greater than maximum connection identifier sequence provided", name: "next connection sequence is not greater than maximum connection identifier sequence provided",
genState: types.NewGenesisState( genState: types.NewGenesisState(
[]types.IdentifiedConnection{ []types.IdentifiedConnection{
types.NewIdentifiedConnection(types.FormatConnectionIdentifier(10), types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), types.NewIdentifiedConnection(types.FormatConnectionIdentifier(10), types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion}, 500)),
}, },
[]types.ConnectionPaths{ []types.ConnectionPaths{
{clientID, []string{connectionID}}, {clientID, []string{connectionID}},

View File

@ -18,13 +18,15 @@ var _ sdk.Msg = &MsgConnectionOpenInit{}
func NewMsgConnectionOpenInit( func NewMsgConnectionOpenInit(
clientID, counterpartyClientID string, clientID, counterpartyClientID string,
counterpartyPrefix commitmenttypes.MerklePrefix, counterpartyPrefix commitmenttypes.MerklePrefix,
version *Version, signer sdk.AccAddress, version *Version, delayPeriod uint64, signer sdk.AccAddress,
) *MsgConnectionOpenInit { ) *MsgConnectionOpenInit {
// counterparty must have the same delay period
counterparty := NewCounterparty(counterpartyClientID, "", counterpartyPrefix) counterparty := NewCounterparty(counterpartyClientID, "", counterpartyPrefix)
return &MsgConnectionOpenInit{ return &MsgConnectionOpenInit{
ClientId: clientID, ClientId: clientID,
Counterparty: counterparty, Counterparty: counterparty,
Version: version, Version: version,
DelayPeriod: delayPeriod,
Signer: signer.String(), Signer: signer.String(),
} }
} }
@ -83,7 +85,8 @@ var _ sdk.Msg = &MsgConnectionOpenTry{}
func NewMsgConnectionOpenTry( func NewMsgConnectionOpenTry(
previousConnectionID, clientID, counterpartyConnectionID, previousConnectionID, clientID, counterpartyConnectionID,
counterpartyClientID string, counterpartyClient exported.ClientState, counterpartyClientID string, counterpartyClient exported.ClientState,
counterpartyPrefix commitmenttypes.MerklePrefix, counterpartyVersions []*Version, counterpartyPrefix commitmenttypes.MerklePrefix,
counterpartyVersions []*Version, delayPeriod uint64,
proofInit, proofClient, proofConsensus []byte, proofInit, proofClient, proofConsensus []byte,
proofHeight, consensusHeight clienttypes.Height, signer sdk.AccAddress, proofHeight, consensusHeight clienttypes.Height, signer sdk.AccAddress,
) *MsgConnectionOpenTry { ) *MsgConnectionOpenTry {
@ -95,6 +98,7 @@ func NewMsgConnectionOpenTry(
ClientState: csAny, ClientState: csAny,
Counterparty: counterparty, Counterparty: counterparty,
CounterpartyVersions: counterpartyVersions, CounterpartyVersions: counterpartyVersions,
DelayPeriod: delayPeriod,
ProofInit: proofInit, ProofInit: proofInit,
ProofClient: proofClient, ProofClient: proofClient,
ProofConsensus: proofConsensus, ProofConsensus: proofConsensus,

View File

@ -87,13 +87,13 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() {
msg *types.MsgConnectionOpenInit msg *types.MsgConnectionOpenInit
expPass bool expPass bool
}{ }{
{"invalid client ID", types.NewMsgConnectionOpenInit("test/iris", "clienttotest", prefix, version, signer), false}, {"invalid client ID", types.NewMsgConnectionOpenInit("test/iris", "clienttotest", prefix, version, 500, signer), false},
{"invalid counterparty client ID", types.NewMsgConnectionOpenInit("clienttotest", "(clienttotest)", prefix, version, signer), false}, {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("clienttotest", "(clienttotest)", prefix, version, 500, signer), false},
{"invalid counterparty connection ID", &types.MsgConnectionOpenInit{connectionID, types.NewCounterparty("clienttotest", "connectiontotest", prefix), version, signer.String()}, false}, {"invalid counterparty connection ID", &types.MsgConnectionOpenInit{connectionID, types.NewCounterparty("clienttotest", "connectiontotest", prefix), version, 500, signer.String()}, false},
{"empty counterparty prefix", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", emptyPrefix, version, signer), false}, {"empty counterparty prefix", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", emptyPrefix, version, 500, signer), false},
{"supplied version fails basic validation", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, &types.Version{}, signer), false}, {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, &types.Version{}, 500, signer), false},
{"empty singer", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, nil), false}, {"empty singer", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, 500, nil), false},
{"success", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, signer), true}, {"success", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, 500, signer), true},
} }
for _, tc := range testCases { for _, tc := range testCases {
@ -131,24 +131,24 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() {
msg *types.MsgConnectionOpenTry msg *types.MsgConnectionOpenTry
expPass bool expPass bool
}{ }{
{"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"invalid connection ID", types.NewMsgConnectionOpenTry("(invalidconnection)", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid connection ID", types.NewMsgConnectionOpenTry("(invalidconnection)", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"invalid client ID", types.NewMsgConnectionOpenTry(connectionID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid client ID", types.NewMsgConnectionOpenTry(connectionID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"invalid counterparty connection ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"invalid counterparty client ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid counterparty client ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"invalid nil counterparty client", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid nil counterparty client", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"invalid client unpacking", &types.MsgConnectionOpenTry{connectionID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, {"invalid client unpacking", &types.MsgConnectionOpenTry{connectionID, "clienttotesta", invalidAny, counterparty, 500, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false},
{"counterparty failed Validate", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"counterparty failed Validate", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"empty counterparty prefix", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"empty counterparty prefix", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"empty counterpartyVersions", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"empty counterpartyVersions", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"empty proofInit", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"empty proofInit", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
{"empty proofClient", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, {"empty proofClient", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false},
{"empty proofConsensus", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, {"empty proofConsensus", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false},
{"invalid proofHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, {"invalid proofHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false},
{"invalid consensusHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, {"invalid consensusHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false},
{"empty singer", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, {"empty singer", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false},
{"success", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, {"success", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true},
{"invalid version", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, {"invalid version", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false},
} }
for _, tc := range testCases { for _, tc := range testCases {

View File

@ -36,7 +36,8 @@ type MsgConnectionOpenInit struct {
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"`
Counterparty Counterparty `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty"` Counterparty Counterparty `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty"`
Version *Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` Version *Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` DelayPeriod uint64 `protobuf:"varint,4,opt,name=delay_period,json=delayPeriod,proto3" json:"delay_period,omitempty" yaml:"delay_period"`
Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"`
} }
func (m *MsgConnectionOpenInit) Reset() { *m = MsgConnectionOpenInit{} } func (m *MsgConnectionOpenInit) Reset() { *m = MsgConnectionOpenInit{} }
@ -118,17 +119,18 @@ type MsgConnectionOpenTry struct {
PreviousConnectionId string `protobuf:"bytes,2,opt,name=previous_connection_id,json=previousConnectionId,proto3" json:"previous_connection_id,omitempty" yaml:"previous_connection_id"` PreviousConnectionId string `protobuf:"bytes,2,opt,name=previous_connection_id,json=previousConnectionId,proto3" json:"previous_connection_id,omitempty" yaml:"previous_connection_id"`
ClientState *types.Any `protobuf:"bytes,3,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` ClientState *types.Any `protobuf:"bytes,3,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"`
Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"` Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"`
CounterpartyVersions []*Version `protobuf:"bytes,5,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` DelayPeriod uint64 `protobuf:"varint,5,opt,name=delay_period,json=delayPeriod,proto3" json:"delay_period,omitempty" yaml:"delay_period"`
ProofHeight types1.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` CounterpartyVersions []*Version `protobuf:"bytes,6,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"`
ProofHeight types1.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"`
// proof of the initialization the connection on Chain A: `UNITIALIZED -> // proof of the initialization the connection on Chain A: `UNITIALIZED ->
// INIT` // INIT`
ProofInit []byte `protobuf:"bytes,7,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` ProofInit []byte `protobuf:"bytes,8,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"`
// proof of client state included in message // proof of client state included in message
ProofClient []byte `protobuf:"bytes,8,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` ProofClient []byte `protobuf:"bytes,9,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"`
// proof of client consensus state // proof of client consensus state
ProofConsensus []byte `protobuf:"bytes,9,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` ProofConsensus []byte `protobuf:"bytes,10,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"`
ConsensusHeight types1.Height `protobuf:"bytes,10,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` ConsensusHeight types1.Height `protobuf:"bytes,11,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"`
Signer string `protobuf:"bytes,11,opt,name=signer,proto3" json:"signer,omitempty"` Signer string `protobuf:"bytes,12,opt,name=signer,proto3" json:"signer,omitempty"`
} }
func (m *MsgConnectionOpenTry) Reset() { *m = MsgConnectionOpenTry{} } func (m *MsgConnectionOpenTry) Reset() { *m = MsgConnectionOpenTry{} }
@ -384,62 +386,65 @@ func init() {
func init() { proto.RegisterFile("ibc/core/connection/v1/tx.proto", fileDescriptor_5d00fde5fc97399e) } func init() { proto.RegisterFile("ibc/core/connection/v1/tx.proto", fileDescriptor_5d00fde5fc97399e) }
var fileDescriptor_5d00fde5fc97399e = []byte{ var fileDescriptor_5d00fde5fc97399e = []byte{
// 880 bytes of a gzipped FileDescriptorProto // 921 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x73, 0xda, 0x58, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x93, 0xdb, 0x44,
0x10, 0x46, 0x06, 0x63, 0x78, 0x70, 0x67, 0x5b, 0x07, 0x58, 0xa7, 0xb3, 0x11, 0xd6, 0xdc, 0xcd, 0x14, 0xb6, 0xce, 0xbe, 0x3b, 0x7b, 0x6d, 0x48, 0xb2, 0xf8, 0xee, 0x84, 0x48, 0x2c, 0x47, 0x03,
0xb9, 0x38, 0x4b, 0xc6, 0xf6, 0xcd, 0xdc, 0xf9, 0xe6, 0x0a, 0xa0, 0x39, 0x17, 0xbe, 0x64, 0x14, 0x83, 0x0b, 0x4e, 0x8a, 0x93, 0x30, 0x03, 0x66, 0x28, 0x6c, 0x37, 0x5c, 0x11, 0xc8, 0x88, 0x00,
0x27, 0x99, 0x71, 0xc3, 0x80, 0x10, 0xb2, 0x06, 0xa3, 0xc7, 0xe8, 0x09, 0x62, 0xa5, 0x4d, 0x93, 0x33, 0x69, 0x3c, 0xb6, 0xbc, 0xd6, 0x69, 0x6c, 0x6b, 0x35, 0x5a, 0xd9, 0x44, 0xb4, 0x34, 0x0c,
0x49, 0x95, 0x9f, 0xe0, 0x9f, 0xe3, 0xd2, 0x65, 0xd2, 0x68, 0x12, 0xbb, 0x49, 0xad, 0x26, 0x93, 0x15, 0x0d, 0x7d, 0xfe, 0x03, 0x7f, 0x22, 0xe5, 0x95, 0x54, 0x1a, 0xb8, 0x6b, 0xa8, 0xd5, 0xd1,
0x2e, 0xa3, 0xf7, 0x24, 0x21, 0x40, 0x8c, 0x21, 0x38, 0x15, 0x5a, 0xed, 0xf7, 0xed, 0xae, 0x76, 0x31, 0xda, 0x95, 0xe4, 0xb5, 0x2d, 0x0f, 0x36, 0x3e, 0x2a, 0xe9, 0xed, 0xfb, 0xde, 0x7b, 0xbb,
0xf7, 0x7b, 0x3c, 0xc0, 0x69, 0x4d, 0x59, 0x94, 0xa1, 0xa1, 0x88, 0x32, 0xd4, 0x75, 0x45, 0x36, 0xef, 0x7d, 0xdf, 0xce, 0x02, 0xd9, 0x1a, 0x18, 0x9a, 0x81, 0x5d, 0xa4, 0x19, 0xd8, 0xb6, 0x91,
0x35, 0xa8, 0x8b, 0x83, 0xb2, 0x68, 0x5e, 0x0a, 0x3d, 0x03, 0x9a, 0x90, 0x2e, 0x68, 0x4d, 0x59, 0xe1, 0x59, 0xd8, 0xd6, 0xe6, 0x4d, 0xcd, 0x7b, 0xa5, 0x3a, 0x2e, 0xf6, 0x30, 0x3c, 0xb5, 0x06,
0x70, 0x01, 0xc2, 0x10, 0x20, 0x0c, 0xca, 0x6c, 0x4e, 0x85, 0x2a, 0xc4, 0x10, 0xd1, 0x7d, 0x22, 0x86, 0x1a, 0x01, 0xd4, 0x05, 0x40, 0x9d, 0x37, 0xa5, 0xaa, 0x89, 0x4d, 0x4c, 0x21, 0x5a, 0xf4,
0x68, 0xf6, 0x67, 0x15, 0x42, 0xf5, 0x42, 0x11, 0xb1, 0xd5, 0xec, 0xb7, 0xc5, 0x86, 0x6e, 0x79, 0xc7, 0xd0, 0xd2, 0xbb, 0x26, 0xc6, 0xe6, 0x04, 0x69, 0xd4, 0x1a, 0xcc, 0x46, 0x5a, 0xdf, 0xf6,
0xae, 0x50, 0xa6, 0x0b, 0x4d, 0xd1, 0x4d, 0x37, 0x0b, 0x79, 0xf2, 0x00, 0xbf, 0x4f, 0x29, 0x25, 0x63, 0x17, 0x57, 0x69, 0x62, 0x21, 0xdb, 0x8b, 0xaa, 0xb0, 0xbf, 0x18, 0xf0, 0xe1, 0x86, 0xad,
0x94, 0x17, 0x03, 0xf9, 0xcf, 0x14, 0xc8, 0x9f, 0x20, 0xb5, 0x16, 0xbc, 0x7f, 0xd4, 0x53, 0xf4, 0x70, 0x75, 0x29, 0x50, 0xf9, 0xed, 0x00, 0x9c, 0x3c, 0x23, 0x66, 0x37, 0x5d, 0xff, 0xca, 0x41,
0x63, 0x5d, 0x33, 0xe9, 0x32, 0x48, 0x93, 0x90, 0x75, 0xad, 0xc5, 0x50, 0x25, 0x6a, 0x27, 0x5d, 0xf6, 0x85, 0x6d, 0x79, 0xb0, 0x09, 0x4a, 0x2c, 0x65, 0xcf, 0x1a, 0x8a, 0x42, 0x5d, 0x68, 0x94,
0xcd, 0x39, 0x36, 0xb7, 0x66, 0x35, 0xba, 0x17, 0x47, 0x7c, 0xe0, 0xe2, 0xa5, 0x14, 0x79, 0x3e, 0x3a, 0xd5, 0x30, 0x90, 0xef, 0xfa, 0xfd, 0xe9, 0xa4, 0xa5, 0xa4, 0x2e, 0x45, 0x2f, 0xb2, 0xff,
0x6e, 0xd1, 0xff, 0x83, 0xac, 0x0c, 0xfb, 0xba, 0xa9, 0x18, 0xbd, 0x86, 0x61, 0x5a, 0xcc, 0x52, 0x8b, 0x21, 0xfc, 0x12, 0x54, 0x0c, 0x3c, 0xb3, 0x3d, 0xe4, 0x3a, 0x7d, 0xd7, 0xf3, 0xc5, 0x83,
0x89, 0xda, 0xc9, 0xec, 0xff, 0x2a, 0x44, 0x7f, 0xb6, 0x50, 0x0b, 0x61, 0xab, 0x89, 0x6b, 0x9b, 0xba, 0xd0, 0x28, 0x3f, 0x7e, 0x5f, 0xcd, 0x3e, 0xb6, 0xda, 0xe5, 0xb0, 0x9d, 0xc2, 0x9b, 0x40,
0x8b, 0x49, 0x23, 0x7c, 0xfa, 0x6f, 0xb0, 0x32, 0x50, 0x0c, 0xa4, 0x41, 0x9d, 0x89, 0xe3, 0x50, 0xce, 0xe9, 0x4b, 0xf1, 0xf0, 0x53, 0x70, 0x3c, 0x47, 0x2e, 0xb1, 0xb0, 0x2d, 0xe6, 0x69, 0x2a,
0xdc, 0xb4, 0x50, 0xcf, 0x08, 0x4c, 0xf2, 0xf1, 0x74, 0x01, 0x24, 0x91, 0xa6, 0xea, 0x8a, 0xc1, 0x79, 0x53, 0xaa, 0x6f, 0x19, 0x4c, 0x4f, 0xf0, 0xb0, 0x05, 0x2a, 0x43, 0x34, 0xe9, 0xfb, 0x3d,
0x24, 0xdc, 0xd2, 0x25, 0xcf, 0x3a, 0x4a, 0xbd, 0xbe, 0xe2, 0x62, 0x9f, 0xae, 0xb8, 0x18, 0xcf, 0x07, 0xb9, 0x16, 0x1e, 0x8a, 0x85, 0xba, 0xd0, 0x28, 0x74, 0xce, 0xc2, 0x40, 0x7e, 0x87, 0x1d,
0x81, 0xad, 0xc8, 0x0f, 0x97, 0x14, 0xd4, 0x83, 0x3a, 0x52, 0xf8, 0xf7, 0x49, 0x90, 0x9b, 0x40, 0x80, 0xf7, 0x2a, 0x7a, 0x99, 0x9a, 0xcf, 0xa9, 0x05, 0x4f, 0xc1, 0x11, 0xb1, 0x4c, 0x1b, 0xb9,
0x9c, 0x1a, 0xd6, 0xb7, 0x74, 0xe6, 0x39, 0x28, 0xf4, 0x0c, 0x65, 0xa0, 0xc1, 0x3e, 0xaa, 0x0f, 0xe2, 0x61, 0x74, 0x6c, 0x3d, 0xb6, 0x5a, 0xc5, 0x9f, 0x5e, 0xcb, 0xb9, 0xbf, 0x5e, 0xcb, 0x39,
0x2b, 0x77, 0xf9, 0x4b, 0x98, 0xbf, 0xed, 0xd8, 0xdc, 0x16, 0xe1, 0x47, 0xe3, 0x78, 0x29, 0xe7, 0x45, 0x06, 0x0f, 0x32, 0x9b, 0xa6, 0x23, 0xe2, 0x60, 0x9b, 0x20, 0xe5, 0xd7, 0x63, 0x50, 0x5d,
0x3b, 0x86, 0x05, 0x1d, 0xb7, 0xe8, 0xc7, 0x20, 0xeb, 0x25, 0x44, 0x66, 0xc3, 0x54, 0xbc, 0x3e, 0x43, 0xbc, 0x70, 0xfd, 0xff, 0xd2, 0xd5, 0xef, 0xc0, 0xa9, 0xe3, 0xa2, 0xb9, 0x85, 0x67, 0xa4,
0xe5, 0x04, 0xb2, 0x3b, 0x82, 0xbf, 0x3b, 0x42, 0x45, 0xb7, 0xaa, 0x1b, 0x8e, 0xcd, 0xfd, 0x34, 0xb7, 0x38, 0x75, 0x14, 0x7f, 0x40, 0xe3, 0x1f, 0x86, 0x81, 0xfc, 0x80, 0xc5, 0x67, 0xe3, 0x14,
0x52, 0x24, 0xe6, 0xf0, 0x52, 0x86, 0x98, 0x4f, 0x5c, 0x6b, 0x62, 0x88, 0x89, 0x05, 0x87, 0x38, 0xbd, 0x9a, 0x38, 0x16, 0x1b, 0xba, 0x18, 0xc2, 0xe7, 0xa0, 0x12, 0x17, 0x24, 0x5e, 0xdf, 0x43,
0x00, 0xf9, 0xb0, 0x5d, 0xf7, 0x26, 0x84, 0x98, 0xe5, 0x52, 0x7c, 0x86, 0x91, 0x56, 0x4b, 0x8e, 0x71, 0x8f, 0xab, 0x2a, 0xe3, 0x9d, 0x9a, 0xf0, 0x4e, 0x6d, 0xdb, 0x3e, 0xdf, 0x39, 0x3e, 0x46,
0xcd, 0x6d, 0x7a, 0x55, 0x47, 0xc5, 0xe1, 0xa5, 0x5c, 0xf8, 0xbd, 0x47, 0x43, 0xf4, 0x19, 0xc8, 0xd1, 0xcb, 0xcc, 0xfc, 0x3a, 0xb2, 0xd6, 0x08, 0x50, 0xd8, 0x93, 0x00, 0xab, 0x53, 0x3c, 0xdc,
0xf6, 0x0c, 0x08, 0xdb, 0xf5, 0x73, 0x45, 0x53, 0xcf, 0x4d, 0x26, 0x89, 0xbf, 0x83, 0x0d, 0xa5, 0x61, 0x8a, 0x73, 0x70, 0xc2, 0xe7, 0xea, 0xc5, 0xcc, 0x20, 0xe2, 0x51, 0x3d, 0xbf, 0x05, 0x95,
0x23, 0x82, 0x19, 0x94, 0x85, 0xff, 0x30, 0xa2, 0xfa, 0x8b, 0x5b, 0xfd, 0xb0, 0x47, 0x61, 0x36, 0x3a, 0xf5, 0x30, 0x90, 0xef, 0xc7, 0x27, 0xce, 0xca, 0xa3, 0xe8, 0x55, 0x7e, 0x3d, 0x0e, 0x23,
0x2f, 0x65, 0xb0, 0x49, 0x90, 0xf4, 0x21, 0x00, 0xc4, 0xab, 0xe9, 0x9a, 0xc9, 0xac, 0x94, 0xa8, 0xf0, 0x25, 0xa8, 0x38, 0x2e, 0xc6, 0xa3, 0xde, 0x25, 0xb2, 0xcc, 0x4b, 0x4f, 0x3c, 0xa6, 0x3d,
0x9d, 0x6c, 0x35, 0xef, 0xd8, 0xdc, 0x7a, 0x98, 0xe9, 0xfa, 0x78, 0x29, 0x8d, 0x0d, 0xac, 0xa8, 0x90, 0xb8, 0x72, 0x4c, 0xa8, 0xf3, 0xa6, 0xfa, 0x05, 0x45, 0x74, 0xde, 0x8b, 0x4e, 0xbe, 0x38,
0x23, 0xbf, 0x22, 0x92, 0x99, 0x49, 0x61, 0xde, 0xc6, 0x78, 0x46, 0xe2, 0xf5, 0x33, 0xd6, 0xb0, 0x13, 0x1f, 0xad, 0xe8, 0x65, 0x6a, 0x32, 0x24, 0x7c, 0x0a, 0x00, 0xf3, 0x5a, 0xb6, 0xe5, 0x89,
0x45, 0xd7, 0xc0, 0xaa, 0xe7, 0x75, 0x77, 0x53, 0x47, 0x7d, 0xc4, 0xa4, 0x31, 0x9d, 0x75, 0x6c, 0xc5, 0xba, 0xd0, 0xa8, 0x74, 0x4e, 0xc2, 0x40, 0xbe, 0xc7, 0x47, 0x46, 0x3e, 0x45, 0x2f, 0x51,
0xae, 0x30, 0x42, 0xf7, 0x01, 0xbc, 0xf4, 0x23, 0x89, 0xe0, 0xbf, 0xa0, 0xdb, 0x60, 0x2d, 0xf0, 0x83, 0x2a, 0xb9, 0x95, 0xec, 0x88, 0x55, 0x16, 0x4b, 0x34, 0xee, 0x6c, 0xb5, 0x22, 0xf3, 0x26,
0xfa, 0x6d, 0x01, 0xf7, 0xb6, 0x85, 0xf3, 0xda, 0xb2, 0xe1, 0x0f, 0x61, 0x34, 0x02, 0x2f, 0xad, 0x15, 0xbb, 0xd4, 0x82, 0x5d, 0x70, 0x27, 0xf6, 0x46, 0xbc, 0xb6, 0xc9, 0x8c, 0x88, 0x80, 0x86,
0x06, 0xaf, 0xbc, 0xf6, 0x0c, 0xc5, 0x97, 0x99, 0x22, 0xbe, 0x22, 0xd8, 0x8c, 0x92, 0x56, 0xa0, 0x4b, 0x61, 0x20, 0x9f, 0x2e, 0x85, 0x27, 0x00, 0x45, 0x7f, 0x9b, 0x65, 0x48, 0x16, 0xe0, 0x08,
0xbd, 0x8f, 0xcb, 0x11, 0xda, 0xab, 0xc8, 0x1d, 0xfa, 0x5f, 0xf0, 0xc3, 0xa8, 0x7e, 0x88, 0xfe, 0xdc, 0x4d, 0xbd, 0x49, 0x5b, 0xca, 0xff, 0xda, 0x16, 0x39, 0x6e, 0xcb, 0x59, 0x32, 0x84, 0xe5,
0x18, 0xc7, 0xe6, 0x72, 0x41, 0x7d, 0x61, 0xd9, 0x64, 0xe5, 0xb0, 0x5c, 0x64, 0xc0, 0x8e, 0x2c, 0x0c, 0x8a, 0x7e, 0x27, 0x5d, 0x8a, 0xdb, 0xb3, 0x10, 0x6e, 0x65, 0x83, 0x70, 0x6b, 0xe0, 0x7e,
0x51, 0x94, 0x16, 0x7f, 0x73, 0x6c, 0x6e, 0x3b, 0x62, 0xe1, 0xc6, 0x02, 0x33, 0x61, 0xe7, 0x88, 0x96, 0x2c, 0x53, 0xdd, 0xfe, 0x79, 0x98, 0xa1, 0xdb, 0xb6, 0x31, 0x86, 0x9f, 0x83, 0xb7, 0x96,
0x26, 0x17, 0x38, 0xb6, 0xc6, 0xe5, 0x9c, 0x58, 0x58, 0xce, 0xe3, 0x32, 0x58, 0x7e, 0x40, 0x19, 0xb5, 0xc7, 0xb4, 0x2b, 0x86, 0x81, 0x5c, 0x4d, 0xf7, 0xc7, 0x4b, 0xae, 0x62, 0xf0, 0x52, 0x33,
0x94, 0x01, 0xd9, 0xee, 0xba, 0x69, 0x58, 0x58, 0x5f, 0xd9, 0xf0, 0x41, 0x18, 0xb8, 0x78, 0x29, 0x80, 0xb4, 0x44, 0xa2, 0x2c, 0x1d, 0x7f, 0x10, 0x06, 0xf2, 0xc3, 0x0c, 0xc2, 0xad, 0x24, 0x16,
0x85, 0x9f, 0xdd, 0xb3, 0x73, 0x5c, 0x03, 0x2b, 0x8b, 0x69, 0x20, 0xf5, 0x20, 0x1a, 0x48, 0x7f, 0x79, 0xe7, 0x92, 0x9e, 0xf7, 0xb8, 0x2e, 0x57, 0xaf, 0x82, 0xc2, 0xde, 0x57, 0xc1, 0xaa, 0x0c,
0x57, 0x0d, 0x80, 0x39, 0x34, 0x50, 0x91, 0x3b, 0x81, 0x06, 0xde, 0x2c, 0x01, 0x66, 0x02, 0x50, 0x0e, 0x6f, 0x51, 0x06, 0x4d, 0xc0, 0xd8, 0xdd, 0xf3, 0x5c, 0x5f, 0x3c, 0xa2, 0x74, 0xe4, 0x2e,
0x83, 0x7a, 0x5b, 0x33, 0xba, 0x8b, 0xea, 0x20, 0x98, 0x5c, 0x43, 0xee, 0xe0, 0xb5, 0x8f, 0x98, 0xd1, 0xd4, 0xa5, 0xe8, 0x45, 0xfa, 0x1f, 0xdd, 0xbb, 0xab, 0x1a, 0x38, 0xde, 0x4f, 0x03, 0xc5,
0x5c, 0x43, 0xee, 0xf8, 0x93, 0x73, 0x95, 0x37, 0xbe, 0x48, 0xf1, 0x07, 0x5c, 0xa4, 0xfb, 0xff, 0x5b, 0xd1, 0x40, 0xe9, 0x7f, 0xd5, 0x00, 0xd8, 0x41, 0x03, 0x6d, 0x63, 0x9c, 0x6a, 0xe0, 0xe7,
0xad, 0x79, 0x50, 0x9a, 0xd6, 0x0b, 0xbf, 0x61, 0xfb, 0x5f, 0xe2, 0x20, 0x7e, 0x82, 0x54, 0xfa, 0x03, 0x20, 0xae, 0x01, 0xba, 0xd8, 0x1e, 0x59, 0xee, 0x74, 0x5f, 0x1d, 0xa4, 0x93, 0xeb, 0x1b,
0x25, 0xa0, 0x23, 0xee, 0x33, 0xbb, 0xd3, 0x44, 0x18, 0x79, 0x0b, 0x60, 0xff, 0x9c, 0x0b, 0xee, 0x63, 0x4a, 0xfb, 0x8c, 0xc9, 0xf5, 0x8d, 0x71, 0x32, 0xb9, 0x48, 0x79, 0xab, 0x44, 0xca, 0xdf,
0xd7, 0x40, 0xbf, 0x00, 0xeb, 0x93, 0x17, 0x86, 0x3f, 0x66, 0x8e, 0x75, 0x6a, 0x58, 0xec, 0xe1, 0x22, 0x91, 0x16, 0xcd, 0x2a, 0x6c, 0x68, 0x96, 0x02, 0xea, 0x9b, 0x7a, 0x91, 0x34, 0xec, 0xf1,
0x3c, 0xe8, 0xe9, 0x89, 0xdd, 0x99, 0xcd, 0x9e, 0xb8, 0x22, 0x77, 0xe6, 0x48, 0x1c, 0x5a, 0x53, 0xdf, 0x79, 0x90, 0x7f, 0x46, 0x4c, 0xf8, 0x03, 0x80, 0x19, 0xef, 0xa8, 0xf3, 0x4d, 0x22, 0xcc,
0xfa, 0x15, 0x05, 0xf2, 0xd1, 0x3b, 0xba, 0x37, 0x73, 0x3c, 0x8f, 0xc1, 0xfe, 0x35, 0x2f, 0xc3, 0x7c, 0x41, 0x48, 0x1f, 0xef, 0x04, 0x4f, 0xf6, 0x00, 0xbf, 0x07, 0xf7, 0xd6, 0x1f, 0x1b, 0x1f,
0xaf, 0xa2, 0xfa, 0xf4, 0xfa, 0xb6, 0x48, 0xdd, 0xdc, 0x16, 0xa9, 0x0f, 0xb7, 0x45, 0xea, 0xed, 0x6d, 0x9d, 0xeb, 0x85, 0xeb, 0x4b, 0x4f, 0x77, 0x41, 0x6f, 0x2e, 0x1c, 0xcd, 0x6c, 0xfb, 0xc2,
0x5d, 0x31, 0x76, 0x73, 0x57, 0x8c, 0xbd, 0xbb, 0x2b, 0xc6, 0xce, 0xfe, 0x51, 0x35, 0xf3, 0xbc, 0x6d, 0x63, 0xbc, 0x43, 0x61, 0x8e, 0xa6, 0xf0, 0x47, 0x01, 0x9c, 0x64, 0x73, 0xf4, 0xd1, 0xd6,
0xdf, 0x14, 0x64, 0xd8, 0x15, 0x65, 0x88, 0xba, 0x10, 0x79, 0x3f, 0xbb, 0xa8, 0xd5, 0x11, 0x2f, 0xf9, 0xe2, 0x08, 0xe9, 0x93, 0x5d, 0x23, 0x92, 0x5d, 0x74, 0xbe, 0x79, 0x73, 0x5d, 0x13, 0xae,
0xc5, 0xe0, 0xa6, 0xbc, 0x77, 0xb0, 0x1b, 0xba, 0x2c, 0x9b, 0x56, 0x4f, 0x41, 0xcd, 0x24, 0x3e, 0xae, 0x6b, 0xc2, 0x1f, 0xd7, 0x35, 0xe1, 0x97, 0x9b, 0x5a, 0xee, 0xea, 0xa6, 0x96, 0xfb, 0xfd,
0x71, 0x0f, 0xbe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x4a, 0xeb, 0x3e, 0xdb, 0x0b, 0x00, 0x00, 0xa6, 0x96, 0x7b, 0xf9, 0x99, 0x69, 0x79, 0x97, 0xb3, 0x81, 0x6a, 0xe0, 0xa9, 0x66, 0x60, 0x32,
0xc5, 0x24, 0xfe, 0x9c, 0x93, 0xe1, 0x58, 0x7b, 0xa5, 0xa5, 0x2f, 0xf4, 0x47, 0x4f, 0xce, 0xb9,
0x47, 0xba, 0xe7, 0x3b, 0x88, 0x0c, 0x8e, 0xe8, 0x8d, 0xfb, 0xe4, 0x9f, 0x00, 0x00, 0x00, 0xff,
0xff, 0xc4, 0x4d, 0xc5, 0x58, 0x53, 0x0c, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -663,7 +668,12 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.Signer) copy(dAtA[i:], m.Signer)
i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer)))
i-- i--
dAtA[i] = 0x22 dAtA[i] = 0x2a
}
if m.DelayPeriod != 0 {
i = encodeVarintTx(dAtA, i, uint64(m.DelayPeriod))
i--
dAtA[i] = 0x20
} }
if m.Version != nil { if m.Version != nil {
{ {
@ -745,7 +755,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.Signer) copy(dAtA[i:], m.Signer)
i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer)))
i-- i--
dAtA[i] = 0x5a dAtA[i] = 0x62
} }
{ {
size, err := m.ConsensusHeight.MarshalToSizedBuffer(dAtA[:i]) size, err := m.ConsensusHeight.MarshalToSizedBuffer(dAtA[:i])
@ -756,27 +766,27 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintTx(dAtA, i, uint64(size)) i = encodeVarintTx(dAtA, i, uint64(size))
} }
i-- i--
dAtA[i] = 0x52 dAtA[i] = 0x5a
if len(m.ProofConsensus) > 0 { if len(m.ProofConsensus) > 0 {
i -= len(m.ProofConsensus) i -= len(m.ProofConsensus)
copy(dAtA[i:], m.ProofConsensus) copy(dAtA[i:], m.ProofConsensus)
i = encodeVarintTx(dAtA, i, uint64(len(m.ProofConsensus))) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofConsensus)))
i-- i--
dAtA[i] = 0x4a dAtA[i] = 0x52
} }
if len(m.ProofClient) > 0 { if len(m.ProofClient) > 0 {
i -= len(m.ProofClient) i -= len(m.ProofClient)
copy(dAtA[i:], m.ProofClient) copy(dAtA[i:], m.ProofClient)
i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClient))) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClient)))
i-- i--
dAtA[i] = 0x42 dAtA[i] = 0x4a
} }
if len(m.ProofInit) > 0 { if len(m.ProofInit) > 0 {
i -= len(m.ProofInit) i -= len(m.ProofInit)
copy(dAtA[i:], m.ProofInit) copy(dAtA[i:], m.ProofInit)
i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit)))
i-- i--
dAtA[i] = 0x3a dAtA[i] = 0x42
} }
{ {
size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i])
@ -787,7 +797,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintTx(dAtA, i, uint64(size)) i = encodeVarintTx(dAtA, i, uint64(size))
} }
i-- i--
dAtA[i] = 0x32 dAtA[i] = 0x3a
if len(m.CounterpartyVersions) > 0 { if len(m.CounterpartyVersions) > 0 {
for iNdEx := len(m.CounterpartyVersions) - 1; iNdEx >= 0; iNdEx-- { for iNdEx := len(m.CounterpartyVersions) - 1; iNdEx >= 0; iNdEx-- {
{ {
@ -799,9 +809,14 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintTx(dAtA, i, uint64(size)) i = encodeVarintTx(dAtA, i, uint64(size))
} }
i-- i--
dAtA[i] = 0x2a dAtA[i] = 0x32
} }
} }
if m.DelayPeriod != 0 {
i = encodeVarintTx(dAtA, i, uint64(m.DelayPeriod))
i--
dAtA[i] = 0x28
}
{ {
size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i])
if err != nil { if err != nil {
@ -1100,6 +1115,9 @@ func (m *MsgConnectionOpenInit) Size() (n int) {
l = m.Version.Size() l = m.Version.Size()
n += 1 + l + sovTx(uint64(l)) n += 1 + l + sovTx(uint64(l))
} }
if m.DelayPeriod != 0 {
n += 1 + sovTx(uint64(m.DelayPeriod))
}
l = len(m.Signer) l = len(m.Signer)
if l > 0 { if l > 0 {
n += 1 + l + sovTx(uint64(l)) n += 1 + l + sovTx(uint64(l))
@ -1136,6 +1154,9 @@ func (m *MsgConnectionOpenTry) Size() (n int) {
} }
l = m.Counterparty.Size() l = m.Counterparty.Size()
n += 1 + l + sovTx(uint64(l)) n += 1 + l + sovTx(uint64(l))
if m.DelayPeriod != 0 {
n += 1 + sovTx(uint64(m.DelayPeriod))
}
if len(m.CounterpartyVersions) > 0 { if len(m.CounterpartyVersions) > 0 {
for _, e := range m.CounterpartyVersions { for _, e := range m.CounterpartyVersions {
l = e.Size() l = e.Size()
@ -1397,6 +1418,25 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
case 4: case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DelayPeriod", wireType)
}
m.DelayPeriod = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.DelayPeriod |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
} }
@ -1668,6 +1708,25 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
case 5: case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DelayPeriod", wireType)
}
m.DelayPeriod = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.DelayPeriod |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 6:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersions", wireType) return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersions", wireType)
} }
@ -1701,7 +1760,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 6: case 7:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType)
} }
@ -1734,7 +1793,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 7: case 8:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType)
} }
@ -1768,7 +1827,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
m.ProofInit = []byte{} m.ProofInit = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 8: case 9:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProofClient", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ProofClient", wireType)
} }
@ -1802,7 +1861,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
m.ProofClient = []byte{} m.ProofClient = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 9: case 10:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProofConsensus", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ProofConsensus", wireType)
} }
@ -1836,7 +1895,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
m.ProofConsensus = []byte{} m.ProofConsensus = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 10: case 11:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ConsensusHeight", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ConsensusHeight", wireType)
} }
@ -1869,7 +1928,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 11: case 12:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType)
} }

View File

@ -32,6 +32,14 @@ type ClientState interface {
Validate() error Validate() error
GetProofSpecs() []*ics23.ProofSpec GetProofSpecs() []*ics23.ProofSpec
// Initialization function
// Clients must validate the initial consensus state, and may store any client-specific metadata
// necessary for correct light client operation
Initialize(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, ConsensusState) error
// Genesis function
ExportMetadata(sdk.KVStore) []GenesisMetadata
// Update and Misbehaviour functions // Update and Misbehaviour functions
CheckHeaderAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Header) (ClientState, ConsensusState, error) CheckHeaderAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Header) (ClientState, ConsensusState, error)
@ -102,6 +110,8 @@ type ClientState interface {
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height Height, height Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix Prefix, prefix Prefix,
proof []byte, proof []byte,
portID, portID,
@ -113,6 +123,8 @@ type ClientState interface {
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height Height, height Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix Prefix, prefix Prefix,
proof []byte, proof []byte,
portID, portID,
@ -124,6 +136,8 @@ type ClientState interface {
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height Height, height Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix Prefix, prefix Prefix,
proof []byte, proof []byte,
portID, portID,
@ -134,6 +148,8 @@ type ClientState interface {
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height Height, height Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix Prefix, prefix Prefix,
proof []byte, proof []byte,
portID, portID,
@ -187,3 +203,12 @@ type Height interface {
Decrement() (Height, bool) Decrement() (Height, bool)
String() string String() string
} }
// GenesisMetadata is a wrapper interface over clienttypes.GenesisMetadata
// all clients must use the concrete implementation in types
type GenesisMetadata interface {
// return store key that contains metadata without clientID-prefix
GetKey() []byte
// returns metadata value
GetValue() []byte
}

View File

@ -6,6 +6,7 @@ type ConnectionI interface {
GetState() int32 GetState() int32
GetCounterparty() CounterpartyConnectionI GetCounterparty() CounterpartyConnectionI
GetVersions() []Version GetVersions() []Version
GetDelayPeriod() uint64
ValidateBasic() error ValidateBasic() error
} }

View File

@ -96,13 +96,22 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
}, },
), ),
}, },
[]clienttypes.IdentifiedGenesisMetadata{
clienttypes.NewIdentifiedGenesisMetadata(
clientID,
[]clienttypes.GenesisMetadata{
clienttypes.NewGenesisMetadata([]byte("key1"), []byte("val1")),
clienttypes.NewGenesisMetadata([]byte("key2"), []byte("val2")),
},
),
},
clienttypes.NewParams(exported.Tendermint, exported.Localhost), clienttypes.NewParams(exported.Tendermint, exported.Localhost),
true, true,
2, 2,
), ),
ConnectionGenesis: connectiontypes.NewGenesisState( ConnectionGenesis: connectiontypes.NewGenesisState(
[]connectiontypes.IdentifiedConnection{ []connectiontypes.IdentifiedConnection{
connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, clientID, connectiontypes.NewCounterparty(clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{ibctesting.ConnectionVersion})), connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, clientID, connectiontypes.NewCounterparty(clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{ibctesting.ConnectionVersion}, 0)),
}, },
[]connectiontypes.ConnectionPaths{ []connectiontypes.ConnectionPaths{
connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), connectiontypes.NewConnectionPaths(clientID, []string{connectionID}),
@ -154,6 +163,15 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
), ),
}, },
nil, nil,
[]clienttypes.IdentifiedGenesisMetadata{
clienttypes.NewIdentifiedGenesisMetadata(
clientID,
[]clienttypes.GenesisMetadata{
clienttypes.NewGenesisMetadata([]byte(""), []byte("val1")),
clienttypes.NewGenesisMetadata([]byte("key2"), []byte("")),
},
),
},
clienttypes.NewParams(exported.Tendermint), clienttypes.NewParams(exported.Tendermint),
false, false,
2, 2,
@ -168,7 +186,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
ClientGenesis: clienttypes.DefaultGenesisState(), ClientGenesis: clienttypes.DefaultGenesisState(),
ConnectionGenesis: connectiontypes.NewGenesisState( ConnectionGenesis: connectiontypes.NewGenesisState(
[]connectiontypes.IdentifiedConnection{ []connectiontypes.IdentifiedConnection{
connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, "(CLIENTIDONE)", connectiontypes.NewCounterparty(clientID, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{connectiontypes.NewVersion("1.1", nil)})), connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, "(CLIENTIDONE)", connectiontypes.NewCounterparty(clientID, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{connectiontypes.NewVersion("1.1", nil)}, 0)),
}, },
[]connectiontypes.ConnectionPaths{ []connectiontypes.ConnectionPaths{
connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), connectiontypes.NewConnectionPaths(clientID, []string{connectionID}),
@ -240,13 +258,22 @@ func (suite *IBCTestSuite) TestInitGenesis() {
}, },
), ),
}, },
[]clienttypes.IdentifiedGenesisMetadata{
clienttypes.NewIdentifiedGenesisMetadata(
clientID,
[]clienttypes.GenesisMetadata{
clienttypes.NewGenesisMetadata([]byte("key1"), []byte("val1")),
clienttypes.NewGenesisMetadata([]byte("key2"), []byte("val2")),
},
),
},
clienttypes.NewParams(exported.Tendermint, exported.Localhost), clienttypes.NewParams(exported.Tendermint, exported.Localhost),
true, true,
0, 0,
), ),
ConnectionGenesis: connectiontypes.NewGenesisState( ConnectionGenesis: connectiontypes.NewGenesisState(
[]connectiontypes.IdentifiedConnection{ []connectiontypes.IdentifiedConnection{
connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, clientID, connectiontypes.NewCounterparty(clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{ibctesting.ConnectionVersion})), connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, clientID, connectiontypes.NewCounterparty(clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{ibctesting.ConnectionVersion}, 0)),
}, },
[]connectiontypes.ConnectionPaths{ []connectiontypes.ConnectionPaths{
connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), connectiontypes.NewConnectionPaths(clientID, []string{connectionID}),

View File

@ -134,7 +134,7 @@ func (k Keeper) SubmitMisbehaviour(goCtx context.Context, msg *clienttypes.MsgSu
func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) { func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx) ctx := sdk.UnwrapSDKContext(goCtx)
connectionID, err := k.ConnectionKeeper.ConnOpenInit(ctx, msg.ClientId, msg.Counterparty, msg.Version) connectionID, err := k.ConnectionKeeper.ConnOpenInit(ctx, msg.ClientId, msg.Counterparty, msg.Version, msg.DelayPeriod)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(err, "connection handshake open init failed") return nil, sdkerrors.Wrap(err, "connection handshake open init failed")
} }
@ -166,7 +166,7 @@ func (k Keeper) ConnectionOpenTry(goCtx context.Context, msg *connectiontypes.Ms
} }
connectionID, err := k.ConnectionKeeper.ConnOpenTry( connectionID, err := k.ConnectionKeeper.ConnOpenTry(
ctx, msg.PreviousConnectionId, msg.Counterparty, msg.ClientId, targetClient, ctx, msg.PreviousConnectionId, msg.Counterparty, msg.DelayPeriod, msg.ClientId, targetClient,
connectiontypes.ProtoVersionsToExported(msg.CounterpartyVersions), msg.ProofInit, msg.ProofClient, msg.ProofConsensus, connectiontypes.ProtoVersionsToExported(msg.CounterpartyVersions), msg.ProofInit, msg.ProofClient, msg.ProofConsensus,
msg.ProofHeight, msg.ConsensusHeight, msg.ProofHeight, msg.ConsensusHeight,
) )

View File

@ -1,6 +1,8 @@
package types package types
import ( import (
"reflect"
ics23 "github.com/confio/ics23/go" ics23 "github.com/confio/ics23/go"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
@ -74,6 +76,20 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState {
) )
} }
// Initialize will check that initial consensus state is equal to the latest consensus state of the initial client.
func (cs ClientState) Initialize(_ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, consState exported.ConsensusState) error {
if !reflect.DeepEqual(cs.ConsensusState, consState) {
return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "consensus state in initial client does not equal initial consensus state. expected: %s, got: %s",
cs.ConsensusState, consState)
}
return nil
}
// ExportMetadata is a no-op since solomachine does not store any metadata in client store
func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata {
return nil
}
// VerifyUpgradeAndUpdateState returns an error since solomachine client does not support upgrades // VerifyUpgradeAndUpdateState returns an error since solomachine client does not support upgrades
func (cs ClientState) VerifyUpgradeAndUpdateState( func (cs ClientState) VerifyUpgradeAndUpdateState(
_ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, _ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore,
@ -238,6 +254,8 @@ func (cs ClientState) VerifyPacketCommitment(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
_ uint64,
_ uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -277,6 +295,8 @@ func (cs ClientState) VerifyPacketAcknowledgement(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
_ uint64,
_ uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -317,6 +337,8 @@ func (cs ClientState) VerifyPacketReceiptAbsence(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
_ uint64,
_ uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -355,6 +377,8 @@ func (cs ClientState) VerifyNextSequenceRecv(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
_ uint64,
_ uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,

View File

@ -7,6 +7,7 @@ import (
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types" "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
) )
@ -80,6 +81,55 @@ func (suite *SoloMachineTestSuite) TestClientStateValidateBasic() {
} }
} }
func (suite *SoloMachineTestSuite) TestInitialize() {
// test singlesig and multisig public keys
for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} {
malleatedConsensus := solomachine.ClientState().ConsensusState
malleatedConsensus.Timestamp = malleatedConsensus.Timestamp + 10
testCases := []struct {
name string
consState exported.ConsensusState
expPass bool
}{
{
"valid consensus state",
solomachine.ConsensusState(),
true,
},
{
"nil consensus state",
nil,
false,
},
{
"invalid consensus state: Tendermint consensus state",
&ibctmtypes.ConsensusState{},
false,
},
{
"invalid consensus state: consensus state does not match consensus state in client",
malleatedConsensus,
false,
},
}
for _, tc := range testCases {
err := solomachine.ClientState().Initialize(
suite.chainA.GetContext(), suite.chainA.Codec,
suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), "solomachine"),
tc.consState,
)
if tc.expPass {
suite.Require().NoError(err, "valid testcase: %s failed", tc.name)
} else {
suite.Require().Error(err, "invalid testcase: %s passed", tc.name)
}
}
}
}
func (suite *SoloMachineTestSuite) TestVerifyClientState() { func (suite *SoloMachineTestSuite) TestVerifyClientState() {
// create client for tendermint so we can use client state for verification // create client for tendermint so we can use client state for verification
clientA, _ := suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) clientA, _ := suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint)
@ -336,7 +386,7 @@ func (suite *SoloMachineTestSuite) TestVerifyClientConsensusState() {
func (suite *SoloMachineTestSuite) TestVerifyConnectionState() { func (suite *SoloMachineTestSuite) TestVerifyConnectionState() {
counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, prefix) counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, prefix)
conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions())) conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0)
path := suite.solomachine.GetConnectionStatePath(testConnectionID) path := suite.solomachine.GetConnectionStatePath(testConnectionID)
@ -587,7 +637,7 @@ func (suite *SoloMachineTestSuite) TestVerifyPacketCommitment() {
expSeq := tc.clientState.Sequence + 1 expSeq := tc.clientState.Sequence + 1
err := tc.clientState.VerifyPacketCommitment( err := tc.clientState.VerifyPacketCommitment(
suite.store, suite.chainA.Codec, solomachine.GetHeight(), tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, commitmentBytes, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, commitmentBytes,
) )
if tc.expPass { if tc.expPass {
@ -674,7 +724,7 @@ func (suite *SoloMachineTestSuite) TestVerifyPacketAcknowledgement() {
expSeq := tc.clientState.Sequence + 1 expSeq := tc.clientState.Sequence + 1
err := tc.clientState.VerifyPacketAcknowledgement( err := tc.clientState.VerifyPacketAcknowledgement(
suite.store, suite.chainA.Codec, solomachine.GetHeight(), tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, ack, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, ack,
) )
if tc.expPass { if tc.expPass {
@ -761,7 +811,7 @@ func (suite *SoloMachineTestSuite) TestVerifyPacketReceiptAbsence() {
expSeq := tc.clientState.Sequence + 1 expSeq := tc.clientState.Sequence + 1
err := tc.clientState.VerifyPacketReceiptAbsence( err := tc.clientState.VerifyPacketReceiptAbsence(
suite.store, suite.chainA.Codec, solomachine.GetHeight(), tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence,
) )
if tc.expPass { if tc.expPass {
@ -848,7 +898,7 @@ func (suite *SoloMachineTestSuite) TestVerifyNextSeqRecv() {
expSeq := tc.clientState.Sequence + 1 expSeq := tc.clientState.Sequence + 1
err := tc.clientState.VerifyNextSequenceRecv( err := tc.clientState.VerifyNextSequenceRecv(
suite.store, suite.chainA.Codec, solomachine.GetHeight(), tc.prefix, tc.proof, testPortID, testChannelID, nextSeqRecv, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, nextSeqRecv,
) )
if tc.expPass { if tc.expPass {

View File

@ -68,7 +68,7 @@ func (suite SoloMachineTestSuite) TestUnmarshalDataByType() {
{ {
"connection", types.CONNECTION, func() { "connection", types.CONNECTION, func() {
counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, prefix) counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, prefix)
conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions())) conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0)
path := solomachine.GetConnectionStatePath("connectionID") path := solomachine.GetConnectionStatePath("connectionID")
data, err = types.ConnectionStateDataBytes(cdc, path, conn) data, err = types.ConnectionStateDataBytes(cdc, path, conn)
@ -99,7 +99,7 @@ func (suite SoloMachineTestSuite) TestUnmarshalDataByType() {
{ {
"bad channel (uses connection data)", types.CHANNEL, func() { "bad channel (uses connection data)", types.CHANNEL, func() {
counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, prefix) counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, prefix)
conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions())) conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0)
path := solomachine.GetConnectionStatePath("connectionID") path := solomachine.GetConnectionStatePath("connectionID")
data, err = types.ConnectionStateDataBytes(cdc, path, conn) data, err = types.ConnectionStateDataBytes(cdc, path, conn)

View File

@ -140,6 +140,18 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState {
} }
} }
// Initialize will check that initial consensus state is a Tendermint consensus state
// and will store ProcessedTime for initial consensus state as ctx.BlockTime()
func (cs ClientState) Initialize(ctx sdk.Context, _ codec.BinaryMarshaler, clientStore sdk.KVStore, consState exported.ConsensusState) error {
if _, ok := consState.(*ConsensusState); !ok {
return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "invalid initial consensus state. expected type: %T, got: %T",
&ConsensusState{}, consState)
}
// set processed time with initial consensus state height equal to initial client state's latest height
SetProcessedTime(clientStore, cs.GetLatestHeight(), uint64(ctx.BlockTime().UnixNano()))
return nil
}
// VerifyClientState verifies a proof of the client state of the running chain // VerifyClientState verifies a proof of the client state of the running chain
// stored on the target machine // stored on the target machine
func (cs ClientState) VerifyClientState( func (cs ClientState) VerifyClientState(
@ -308,6 +320,8 @@ func (cs ClientState) VerifyPacketCommitment(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -320,6 +334,11 @@ func (cs ClientState) VerifyPacketCommitment(
return err return err
} }
// check delay period has passed
if err := verifyDelayPeriodPassed(store, height, currentTimestamp, delayPeriod); err != nil {
return err
}
commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, sequence)) commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, sequence))
path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath) path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath)
if err != nil { if err != nil {
@ -339,6 +358,8 @@ func (cs ClientState) VerifyPacketAcknowledgement(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -351,6 +372,11 @@ func (cs ClientState) VerifyPacketAcknowledgement(
return err return err
} }
// check delay period has passed
if err := verifyDelayPeriodPassed(store, height, currentTimestamp, delayPeriod); err != nil {
return err
}
ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, sequence)) ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, sequence))
path, err := commitmenttypes.ApplyPrefix(prefix, ackPath) path, err := commitmenttypes.ApplyPrefix(prefix, ackPath)
if err != nil { if err != nil {
@ -371,6 +397,8 @@ func (cs ClientState) VerifyPacketReceiptAbsence(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -382,6 +410,11 @@ func (cs ClientState) VerifyPacketReceiptAbsence(
return err return err
} }
// check delay period has passed
if err := verifyDelayPeriodPassed(store, height, currentTimestamp, delayPeriod); err != nil {
return err
}
receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, sequence)) receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, sequence))
path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath) path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath)
if err != nil { if err != nil {
@ -401,6 +434,8 @@ func (cs ClientState) VerifyNextSequenceRecv(
store sdk.KVStore, store sdk.KVStore,
cdc codec.BinaryMarshaler, cdc codec.BinaryMarshaler,
height exported.Height, height exported.Height,
currentTimestamp uint64,
delayPeriod uint64,
prefix exported.Prefix, prefix exported.Prefix,
proof []byte, proof []byte,
portID, portID,
@ -412,6 +447,11 @@ func (cs ClientState) VerifyNextSequenceRecv(
return err return err
} }
// check delay period has passed
if err := verifyDelayPeriodPassed(store, height, currentTimestamp, delayPeriod); err != nil {
return err
}
nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID)) nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID))
path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath) path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath)
if err != nil { if err != nil {
@ -427,6 +467,23 @@ func (cs ClientState) VerifyNextSequenceRecv(
return nil return nil
} }
// verifyDelayPeriodPassed will ensure that at least delayPeriod amount of time has passed since consensus state was submitted
// before allowing verification to continue.
func verifyDelayPeriodPassed(store sdk.KVStore, proofHeight exported.Height, currentTimestamp, delayPeriod uint64) error {
// check that executing chain's timestamp has passed consensusState's processed time + delay period
processedTime, ok := GetProcessedTime(store, proofHeight)
if !ok {
return sdkerrors.Wrapf(ErrProcessedTimeNotFound, "processed time not found for height: %s", proofHeight)
}
validTime := processedTime + delayPeriod
// NOTE: delay period is inclusive, so if currentTimestamp is validTime, then we return no error
if validTime > currentTimestamp {
return sdkerrors.Wrapf(ErrDelayPeriodNotPassed, "cannot verify packet until time: %d, current time: %d",
validTime, currentTimestamp)
}
return nil
}
// produceVerificationArgs perfoms the basic checks on the arguments that are // produceVerificationArgs perfoms the basic checks on the arguments that are
// shared between the verification functions and returns the unmarshalled // shared between the verification functions and returns the unmarshalled
// merkle proof, the consensus state and an error if one occurred. // merkle proof, the consensus state and an error if one occurred.

View File

@ -1,6 +1,8 @@
package types_test package types_test
import ( import (
"time"
ics23 "github.com/confio/ics23/go" ics23 "github.com/confio/ics23/go"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
@ -98,6 +100,41 @@ func (suite *TendermintTestSuite) TestValidate() {
} }
} }
func (suite *TendermintTestSuite) TestInitialize() {
testCases := []struct {
name string
consensusState exported.ConsensusState
expPass bool
}{
{
name: "valid consensus",
consensusState: &types.ConsensusState{},
expPass: true,
},
{
name: "invalid consensus: consensus state is solomachine consensus",
consensusState: ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2).ConsensusState(),
expPass: false,
},
}
clientA, err := suite.coordinator.CreateClient(suite.chainA, suite.chainB, exported.Tendermint)
suite.Require().NoError(err)
clientState := suite.chainA.GetClientState(clientA)
store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
for _, tc := range testCases {
err := clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, store, tc.consensusState)
if tc.expPass {
suite.Require().NoError(err, "valid case returned an error")
} else {
suite.Require().Error(err, "invalid case didn't return an error")
}
}
}
func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
testCases := []struct { testCases := []struct {
name string name string
@ -335,6 +372,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
var ( var (
clientState *types.ClientState clientState *types.ClientState
proof []byte proof []byte
delayPeriod uint64
proofHeight exported.Height proofHeight exported.Height
prefix commitmenttypes.MerklePrefix prefix commitmenttypes.MerklePrefix
) )
@ -347,6 +385,20 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
{ {
"successful verification", func() {}, true, "successful verification", func() {}, true,
}, },
{
name: "delay period has passed",
malleate: func() {
delayPeriod = uint64(time.Second.Nanoseconds())
},
expPass: true,
},
{
name: "delay period has not passed",
malleate: func() {
delayPeriod = uint64(time.Hour.Nanoseconds())
},
expPass: false,
},
{ {
"ApplyPrefix failed", func() { "ApplyPrefix failed", func() {
prefix = commitmenttypes.MerklePrefix{} prefix = commitmenttypes.MerklePrefix{}
@ -396,9 +448,10 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() {
store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
currentTime := uint64(suite.chainA.GetContext().BlockTime().UnixNano())
commitment := channeltypes.CommitPacket(suite.chainA.App.IBCKeeper.Codec(), packet) commitment := channeltypes.CommitPacket(suite.chainA.App.IBCKeeper.Codec(), packet)
err = clientState.VerifyPacketCommitment( err = clientState.VerifyPacketCommitment(
store, suite.chainA.Codec, proofHeight, &prefix, proof, store, suite.chainA.Codec, proofHeight, currentTime, delayPeriod, &prefix, proof,
packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment,
) )
@ -418,6 +471,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
var ( var (
clientState *types.ClientState clientState *types.ClientState
proof []byte proof []byte
delayPeriod uint64
proofHeight exported.Height proofHeight exported.Height
prefix commitmenttypes.MerklePrefix prefix commitmenttypes.MerklePrefix
) )
@ -430,6 +484,20 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
{ {
"successful verification", func() {}, true, "successful verification", func() {}, true,
}, },
{
name: "delay period has passed",
malleate: func() {
delayPeriod = uint64(time.Second.Nanoseconds())
},
expPass: true,
},
{
name: "delay period has not passed",
malleate: func() {
delayPeriod = uint64(time.Hour.Nanoseconds())
},
expPass: false,
},
{ {
"ApplyPrefix failed", func() { "ApplyPrefix failed", func() {
prefix = commitmenttypes.MerklePrefix{} prefix = commitmenttypes.MerklePrefix{}
@ -485,8 +553,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() {
store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
currentTime := uint64(suite.chainA.GetContext().BlockTime().UnixNano())
err = clientState.VerifyPacketAcknowledgement( err = clientState.VerifyPacketAcknowledgement(
store, suite.chainA.Codec, proofHeight, &prefix, proof, store, suite.chainA.Codec, proofHeight, currentTime, delayPeriod, &prefix, proof,
packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ibcmock.MockAcknowledgement, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ibcmock.MockAcknowledgement,
) )
@ -506,6 +575,7 @@ func (suite *TendermintTestSuite) TestVerifyPacketReceiptAbsence() {
var ( var (
clientState *types.ClientState clientState *types.ClientState
proof []byte proof []byte
delayPeriod uint64
proofHeight exported.Height proofHeight exported.Height
prefix commitmenttypes.MerklePrefix prefix commitmenttypes.MerklePrefix
) )
@ -518,6 +588,20 @@ func (suite *TendermintTestSuite) TestVerifyPacketReceiptAbsence() {
{ {
"successful verification", func() {}, true, "successful verification", func() {}, true,
}, },
{
name: "delay period has passed",
malleate: func() {
delayPeriod = uint64(time.Second.Nanoseconds())
},
expPass: true,
},
{
name: "delay period has not passed",
malleate: func() {
delayPeriod = uint64(time.Hour.Nanoseconds())
},
expPass: false,
},
{ {
"ApplyPrefix failed", func() { "ApplyPrefix failed", func() {
prefix = commitmenttypes.MerklePrefix{} prefix = commitmenttypes.MerklePrefix{}
@ -572,8 +656,9 @@ func (suite *TendermintTestSuite) TestVerifyPacketReceiptAbsence() {
store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
currentTime := uint64(suite.chainA.GetContext().BlockTime().UnixNano())
err = clientState.VerifyPacketReceiptAbsence( err = clientState.VerifyPacketReceiptAbsence(
store, suite.chainA.Codec, proofHeight, &prefix, proof, store, suite.chainA.Codec, proofHeight, currentTime, delayPeriod, &prefix, proof,
packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(),
) )
@ -593,6 +678,7 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
var ( var (
clientState *types.ClientState clientState *types.ClientState
proof []byte proof []byte
delayPeriod uint64
proofHeight exported.Height proofHeight exported.Height
prefix commitmenttypes.MerklePrefix prefix commitmenttypes.MerklePrefix
) )
@ -605,6 +691,20 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
{ {
"successful verification", func() {}, true, "successful verification", func() {}, true,
}, },
{
name: "delay period has passed",
malleate: func() {
delayPeriod = uint64(time.Second.Nanoseconds())
},
expPass: true,
},
{
name: "delay period has not passed",
malleate: func() {
delayPeriod = uint64(time.Hour.Nanoseconds())
},
expPass: false,
},
{ {
"ApplyPrefix failed", func() { "ApplyPrefix failed", func() {
prefix = commitmenttypes.MerklePrefix{} prefix = commitmenttypes.MerklePrefix{}
@ -663,8 +763,9 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() {
store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
currentTime := uint64(suite.chainA.GetContext().BlockTime().UnixNano())
err = clientState.VerifyNextSequenceRecv( err = clientState.VerifyNextSequenceRecv(
store, suite.chainA.Codec, proofHeight, &prefix, proof, store, suite.chainA.Codec, proofHeight, currentTime, delayPeriod, &prefix, proof,
packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()+1, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()+1,
) )

View File

@ -14,8 +14,7 @@ import (
// NewConsensusState creates a new ConsensusState instance. // NewConsensusState creates a new ConsensusState instance.
func NewConsensusState( func NewConsensusState(
timestamp time.Time, root commitmenttypes.MerkleRoot, timestamp time.Time, root commitmenttypes.MerkleRoot, nextValsHash tmbytes.HexBytes,
nextValsHash tmbytes.HexBytes,
) *ConsensusState { ) *ConsensusState {
return &ConsensusState{ return &ConsensusState{
Timestamp: timestamp, Timestamp: timestamp,
@ -34,12 +33,14 @@ func (cs ConsensusState) GetRoot() exported.Root {
return cs.Root return cs.Root
} }
// GetTimestamp returns block time in nanoseconds at which the consensus state was stored // GetTimestamp returns block time in nanoseconds of the header that created consensus state
func (cs ConsensusState) GetTimestamp() uint64 { func (cs ConsensusState) GetTimestamp() uint64 {
return uint64(cs.Timestamp.UnixNano()) return uint64(cs.Timestamp.UnixNano())
} }
// ValidateBasic defines a basic validation for the tendermint consensus state. // ValidateBasic defines a basic validation for the tendermint consensus state.
// NOTE: ProcessedTimestamp may be zero if this is an initial consensus state passed in by relayer
// as opposed to a consensus state constructed by the chain.
func (cs ConsensusState) ValidateBasic() error { func (cs ConsensusState) ValidateBasic() error {
if cs.Root.Empty() { if cs.Root.Empty() {
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty") return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty")

View File

@ -16,8 +16,10 @@ var (
ErrInvalidHeaderHeight = sdkerrors.Register(SubModuleName, 5, "invalid header height") ErrInvalidHeaderHeight = sdkerrors.Register(SubModuleName, 5, "invalid header height")
ErrInvalidHeader = sdkerrors.Register(SubModuleName, 6, "invalid header") ErrInvalidHeader = sdkerrors.Register(SubModuleName, 6, "invalid header")
ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 7, "invalid max clock drift") ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 7, "invalid max clock drift")
ErrTrustingPeriodExpired = sdkerrors.Register(SubModuleName, 8, "time since latest trusted state has passed the trusting period") ErrProcessedTimeNotFound = sdkerrors.Register(SubModuleName, 8, "processed time not found")
ErrUnbondingPeriodExpired = sdkerrors.Register(SubModuleName, 9, "time since latest trusted state has passed the unbonding period") ErrDelayPeriodNotPassed = sdkerrors.Register(SubModuleName, 9, "packet-specified delay period has not been reached")
ErrInvalidProofSpecs = sdkerrors.Register(SubModuleName, 10, "invalid proof specs") ErrTrustingPeriodExpired = sdkerrors.Register(SubModuleName, 10, "time since latest trusted state has passed the trusting period")
ErrInvalidValidatorSet = sdkerrors.Register(SubModuleName, 11, "invalid validator set") ErrUnbondingPeriodExpired = sdkerrors.Register(SubModuleName, 11, "time since latest trusted state has passed the unbonding period")
ErrInvalidProofSpecs = sdkerrors.Register(SubModuleName, 12, "invalid proof specs")
ErrInvalidValidatorSet = sdkerrors.Register(SubModuleName, 13, "invalid validator set")
) )

View File

@ -0,0 +1,21 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
)
// ExportMetadata exports all the processed times in the client store so they can be included in clients genesis
// and imported by a ClientKeeper
func (cs ClientState) ExportMetadata(store sdk.KVStore) []exported.GenesisMetadata {
gm := make([]exported.GenesisMetadata, 0)
IterateProcessedTime(store, func(key, val []byte) bool {
gm = append(gm, clienttypes.NewGenesisMetadata(key, val))
return false
})
if len(gm) == 0 {
return nil
}
return gm
}

View File

@ -0,0 +1,38 @@
package types_test
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types"
)
func (suite *TendermintTestSuite) TestExportMetadata() {
clientState := types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false)
suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), "clientA", clientState)
gm := clientState.ExportMetadata(suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), "clientA"))
suite.Require().Nil(gm, "client with no metadata returned non-nil exported metadata")
clientStore := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), "clientA")
// set some processed times
timestamp1 := uint64(time.Now().UnixNano())
timestamp2 := uint64(time.Now().Add(time.Minute).UnixNano())
timestampBz1 := sdk.Uint64ToBigEndian(timestamp1)
timestampBz2 := sdk.Uint64ToBigEndian(timestamp2)
types.SetProcessedTime(clientStore, clienttypes.NewHeight(0, 1), timestamp1)
types.SetProcessedTime(clientStore, clienttypes.NewHeight(0, 2), timestamp2)
gm = clientState.ExportMetadata(suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), "clientA"))
suite.Require().NotNil(gm, "client with metadata returned nil exported metadata")
suite.Require().Len(gm, 2, "exported metadata has unexpected length")
suite.Require().Equal(types.ProcessedTimeKey(clienttypes.NewHeight(0, 1)), gm[0].GetKey(), "metadata has unexpected key")
suite.Require().Equal(timestampBz1, gm[0].GetValue(), "metadata has unexpected value")
suite.Require().Equal(types.ProcessedTimeKey(clienttypes.NewHeight(0, 2)), gm[1].GetKey(), "metadata has unexpected key")
suite.Require().Equal(timestampBz2, gm[1].GetValue(), "metadata has unexpected value")
}

View File

@ -53,7 +53,7 @@ func (cs ClientState) CheckProposedHeaderAndUpdateState(
// if the client is expired we unexpire the client using softer validation, otherwise // if the client is expired we unexpire the client using softer validation, otherwise
// full validation on the header is performed. // full validation on the header is performed.
if cs.IsExpired(consensusState.Timestamp, ctx.BlockTime()) { if cs.IsExpired(consensusState.Timestamp, ctx.BlockTime()) {
return cs.unexpireClient(consensusState, tmHeader, ctx.BlockTime()) return cs.unexpireClient(ctx, clientStore, consensusState, tmHeader, ctx.BlockTime())
} }
// NOTE: the client may be frozen again since the misbehaviour evidence may // NOTE: the client may be frozen again since the misbehaviour evidence may
@ -61,7 +61,7 @@ func (cs ClientState) CheckProposedHeaderAndUpdateState(
return cs.CheckHeaderAndUpdateState(ctx, cdc, clientStore, header) return cs.CheckHeaderAndUpdateState(ctx, cdc, clientStore, header)
case cs.AllowUpdateAfterExpiry && cs.IsExpired(consensusState.Timestamp, ctx.BlockTime()): case cs.AllowUpdateAfterExpiry && cs.IsExpired(consensusState.Timestamp, ctx.BlockTime()):
return cs.unexpireClient(consensusState, tmHeader, ctx.BlockTime()) return cs.unexpireClient(ctx, clientStore, consensusState, tmHeader, ctx.BlockTime())
default: default:
return nil, nil, sdkerrors.Wrap(clienttypes.ErrUpdateClientFailed, "client cannot be updated with proposal") return nil, nil, sdkerrors.Wrap(clienttypes.ErrUpdateClientFailed, "client cannot be updated with proposal")
@ -72,7 +72,7 @@ func (cs ClientState) CheckProposedHeaderAndUpdateState(
// unexpireClient checks if the proposed header is sufficient to update an expired client. // unexpireClient checks if the proposed header is sufficient to update an expired client.
// The client is updated if no error occurs. // The client is updated if no error occurs.
func (cs ClientState) unexpireClient( func (cs ClientState) unexpireClient(
consensusState *ConsensusState, header *Header, currentTimestamp time.Time, ctx sdk.Context, clientStore sdk.KVStore, consensusState *ConsensusState, header *Header, currentTimestamp time.Time,
) (exported.ClientState, exported.ConsensusState, error) { ) (exported.ClientState, exported.ConsensusState, error) {
// the client is expired and either AllowUpdateAfterMisbehaviour or AllowUpdateAfterExpiry // the client is expired and either AllowUpdateAfterMisbehaviour or AllowUpdateAfterExpiry
@ -81,7 +81,7 @@ func (cs ClientState) unexpireClient(
return nil, nil, err return nil, nil, err
} }
newClientState, consensusState := update(&cs, header) newClientState, consensusState := update(ctx, clientStore, &cs, header)
return newClientState, consensusState, nil return newClientState, consensusState, nil
} }

View File

@ -1,6 +1,8 @@
package types package types
import ( import (
"strings"
"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"
@ -9,6 +11,9 @@ import (
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
) )
// KeyProcessedTime is appended to consensus state key to store the processed time
var KeyProcessedTime = []byte("/processedTime")
// GetConsensusState retrieves the consensus state from the client prefixed // GetConsensusState retrieves the consensus state from the client prefixed
// store. An error is returned if the consensus state does not exist. // store. An error is returned if the consensus state does not exist.
func GetConsensusState(store sdk.KVStore, cdc codec.BinaryMarshaler, height exported.Height) (*ConsensusState, error) { func GetConsensusState(store sdk.KVStore, cdc codec.BinaryMarshaler, height exported.Height) (*ConsensusState, error) {
@ -35,3 +40,50 @@ func GetConsensusState(store sdk.KVStore, cdc codec.BinaryMarshaler, height expo
return consensusState, nil return consensusState, nil
} }
// IterateProcessedTime iterates through the prefix store and applies the callback.
// If the cb returns true, then iterator will close and stop.
func IterateProcessedTime(store sdk.KVStore, cb func(key, val []byte) bool) {
iterator := sdk.KVStorePrefixIterator(store, []byte(host.KeyConsensusStatePrefix))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
keySplit := strings.Split(string(iterator.Key()), "/")
// processed time key in prefix store has format: "consensusState/<height>/processedTime"
if len(keySplit) != 3 || keySplit[2] != "processedTime" {
// ignore all consensus state keys
continue
}
if cb(iterator.Key(), iterator.Value()) {
break
}
}
}
// ProcessedTime Store code
// ProcessedTimeKey returns the key under which the processed time will be stored in the client store.
func ProcessedTimeKey(height exported.Height) []byte {
return append(host.ConsensusStateKey(height), KeyProcessedTime...)
}
// SetProcessedTime stores the time at which a header was processed and the corresponding consensus state was created.
// This is useful when validating whether a packet has reached the specified delay period in the tendermint client's
// verification functions
func SetProcessedTime(clientStore sdk.KVStore, height exported.Height, timeNs uint64) {
key := ProcessedTimeKey(height)
val := sdk.Uint64ToBigEndian(timeNs)
clientStore.Set(key, val)
}
// GetProcessedTime gets the time (in nanoseconds) at which this chain received and processed a tendermint header.
// This is used to validate that a received packet has passed the delay period.
func GetProcessedTime(clientStore sdk.KVStore, height exported.Height) (uint64, bool) {
key := ProcessedTimeKey(height)
bz := clientStore.Get(key)
if bz == nil {
return 0, false
}
return sdk.BigEndianToUint64(bz), true
}

View File

@ -7,6 +7,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types" solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types"
"github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
) )
func (suite *TendermintTestSuite) TestGetConsensusState() { func (suite *TendermintTestSuite) TestGetConsensusState() {
@ -74,3 +75,39 @@ func (suite *TendermintTestSuite) TestGetConsensusState() {
}) })
} }
} }
func (suite *TendermintTestSuite) TestGetProcessedTime() {
// Verify ProcessedTime on CreateClient
// coordinator increments time before creating client
expectedTime := suite.chainA.CurrentHeader.Time.Add(ibctesting.TimeIncrement)
clientA, err := suite.coordinator.CreateClient(suite.chainA, suite.chainB, exported.Tendermint)
suite.Require().NoError(err)
clientState := suite.chainA.GetClientState(clientA)
height := clientState.GetLatestHeight()
store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
actualTime, ok := types.GetProcessedTime(store, height)
suite.Require().True(ok, "could not retrieve processed time for stored consensus state")
suite.Require().Equal(uint64(expectedTime.UnixNano()), actualTime, "retrieved processed time is not expected value")
// Verify ProcessedTime on UpdateClient
// coordinator increments time before updating client
expectedTime = suite.chainA.CurrentHeader.Time.Add(ibctesting.TimeIncrement)
err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint)
suite.Require().NoError(err)
clientState = suite.chainA.GetClientState(clientA)
height = clientState.GetLatestHeight()
store = suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
actualTime, ok = types.GetProcessedTime(store, height)
suite.Require().True(ok, "could not retrieve processed time for stored consensus state")
suite.Require().Equal(uint64(expectedTime.UnixNano()), actualTime, "retrieved processed time is not expected value")
// try to get processed time for height that doesn't exist in store
_, ok = types.GetProcessedTime(store, clienttypes.NewHeight(1, 1))
suite.Require().False(ok, "retrieved processed time for a non-existent consensus state")
}

View File

@ -60,7 +60,7 @@ func (cs ClientState) CheckHeaderAndUpdateState(
return nil, nil, err return nil, nil, err
} }
newClientState, consensusState := update(&cs, tmHeader) newClientState, consensusState := update(ctx, clientStore, &cs, tmHeader)
return newClientState, consensusState, nil return newClientState, consensusState, nil
} }
@ -166,8 +166,8 @@ func checkValidity(
return nil return nil
} }
// update the consensus state from a new header // update the consensus state from a new header and set processed time metadata
func update(clientState *ClientState, header *Header) (*ClientState, *ConsensusState) { func update(ctx sdk.Context, clientStore sdk.KVStore, clientState *ClientState, header *Header) (*ClientState, *ConsensusState) {
height := header.GetHeight().(clienttypes.Height) height := header.GetHeight().(clienttypes.Height)
if height.GT(clientState.LatestHeight) { if height.GT(clientState.LatestHeight) {
clientState.LatestHeight = height clientState.LatestHeight = height
@ -178,5 +178,9 @@ func update(clientState *ClientState, header *Header) (*ClientState, *ConsensusS
NextValidatorsHash: header.Header.NextValidatorsHash, NextValidatorsHash: header.Header.NextValidatorsHash,
} }
// set context time as processed time as this is state internal to tendermint client logic.
// client state and consensus state will be set by client keeper
SetProcessedTime(clientStore, header.GetHeight(), uint64(ctx.BlockTime().UnixNano()))
return clientState, consensusState return clientState, consensusState
} }

View File

@ -116,6 +116,8 @@ func (cs ClientState) VerifyUpgradeAndUpdateState(
// The timestamp and the NextValidatorsHash of the consensus state is the blocktime and NextValidatorsHash // The timestamp and the NextValidatorsHash of the consensus state is the blocktime and NextValidatorsHash
// of the last block committed by the old chain. This will allow the first block of the new chain to be verified against // of the last block committed by the old chain. This will allow the first block of the new chain to be verified against
// the last validators of the old chain so long as it is submitted within the TrustingPeriod of this client. // the last validators of the old chain so long as it is submitted within the TrustingPeriod of this client.
// NOTE: We do not set processed time for this consensus state since this consensus state should not be used for packet verification
// as the root is empty. The next consensus state submitted using update will be usable for packet-verification.
newConsState := NewConsensusState( newConsState := NewConsensusState(
tmUpgradeConsState.Timestamp, commitmenttypes.MerkleRoot{}, tmUpgradeConsState.NextValidatorsHash, tmUpgradeConsState.Timestamp, commitmenttypes.MerkleRoot{}, tmUpgradeConsState.NextValidatorsHash,
) )

View File

@ -74,6 +74,19 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState {
return &cs return &cs
} }
// Initialize ensures that initial consensus state for localhost is nil
func (cs ClientState) Initialize(_ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, consState exported.ConsensusState) error {
if consState != nil {
return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "initial consensus state for localhost must be nil.")
}
return nil
}
// ExportMetadata is a no-op for localhost client
func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata {
return nil
}
// CheckHeaderAndUpdateState updates the localhost client. It only needs access to the context // CheckHeaderAndUpdateState updates the localhost client. It only needs access to the context
func (cs *ClientState) CheckHeaderAndUpdateState( func (cs *ClientState) CheckHeaderAndUpdateState(
ctx sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, _ exported.Header, ctx sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, _ exported.Header,
@ -216,6 +229,8 @@ func (cs ClientState) VerifyPacketCommitment(
store sdk.KVStore, store sdk.KVStore,
_ codec.BinaryMarshaler, _ codec.BinaryMarshaler,
_ exported.Height, _ exported.Height,
_ uint64,
_ uint64,
_ exported.Prefix, _ exported.Prefix,
_ []byte, _ []byte,
portID, portID,
@ -246,6 +261,8 @@ func (cs ClientState) VerifyPacketAcknowledgement(
store sdk.KVStore, store sdk.KVStore,
_ codec.BinaryMarshaler, _ codec.BinaryMarshaler,
_ exported.Height, _ exported.Height,
_ uint64,
_ uint64,
_ exported.Prefix, _ exported.Prefix,
_ []byte, _ []byte,
portID, portID,
@ -277,6 +294,8 @@ func (cs ClientState) VerifyPacketReceiptAbsence(
store sdk.KVStore, store sdk.KVStore,
_ codec.BinaryMarshaler, _ codec.BinaryMarshaler,
_ exported.Height, _ exported.Height,
_ uint64,
_ uint64,
_ exported.Prefix, _ exported.Prefix,
_ []byte, _ []byte,
portID, portID,
@ -299,6 +318,8 @@ func (cs ClientState) VerifyNextSequenceRecv(
store sdk.KVStore, store sdk.KVStore,
_ codec.BinaryMarshaler, _ codec.BinaryMarshaler,
_ exported.Height, _ exported.Height,
_ uint64,
_ uint64,
_ exported.Prefix, _ exported.Prefix,
_ []byte, _ []byte,
portID, portID,

View File

@ -7,6 +7,8 @@ import (
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types"
host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types"
"github.com/cosmos/cosmos-sdk/x/ibc/light-clients/09-localhost/types" "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/09-localhost/types"
) )
@ -50,6 +52,37 @@ func (suite *LocalhostTestSuite) TestValidate() {
} }
} }
func (suite *LocalhostTestSuite) TestInitialize() {
testCases := []struct {
name string
consState exported.ConsensusState
expPass bool
}{
{
"valid initialization",
nil,
true,
},
{
"invalid consenus state",
&ibctmtypes.ConsensusState{},
false,
},
}
clientState := types.NewClientState("chainID", clienttypes.NewHeight(3, 10))
for _, tc := range testCases {
err := clientState.Initialize(suite.ctx, suite.cdc, suite.store, tc.consState)
if tc.expPass {
suite.Require().NoError(err, "valid testcase: %s failed", tc.name)
} else {
suite.Require().Error(err, "invalid testcase: %s passed", tc.name)
}
}
}
func (suite *LocalhostTestSuite) TestVerifyClientState() { func (suite *LocalhostTestSuite) TestVerifyClientState() {
clientState := types.NewClientState("chainID", clientHeight) clientState := types.NewClientState("chainID", clientHeight)
invalidClient := types.NewClientState("chainID", clienttypes.NewHeight(0, 12)) invalidClient := types.NewClientState("chainID", clienttypes.NewHeight(0, 12))
@ -145,8 +178,8 @@ func (suite *LocalhostTestSuite) TestProposedHeaderAndUpdateState() {
func (suite *LocalhostTestSuite) TestVerifyConnectionState() { func (suite *LocalhostTestSuite) TestVerifyConnectionState() {
counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, commitmenttypes.NewMerklePrefix([]byte("ibc"))) counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, commitmenttypes.NewMerklePrefix([]byte("ibc")))
conn1 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, []*connectiontypes.Version{connectiontypes.NewVersion("1", nil)}) conn1 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, []*connectiontypes.Version{connectiontypes.NewVersion("1", nil)}, 0)
conn2 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, []*connectiontypes.Version{connectiontypes.NewVersion("2", nil)}) conn2 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, []*connectiontypes.Version{connectiontypes.NewVersion("2", nil)}, 0)
testCases := []struct { testCases := []struct {
name string name string
@ -336,7 +369,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketCommitment() {
tc.malleate() tc.malleate()
err := tc.clientState.VerifyPacketCommitment( err := tc.clientState.VerifyPacketCommitment(
suite.store, suite.cdc, clientHeight, nil, []byte{}, testPortID, testChannelID, testSequence, tc.commitment, suite.store, suite.cdc, clientHeight, 0, 0, nil, []byte{}, testPortID, testChannelID, testSequence, tc.commitment,
) )
if tc.expPass { if tc.expPass {
@ -395,7 +428,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgement() {
tc.malleate() tc.malleate()
err := tc.clientState.VerifyPacketAcknowledgement( err := tc.clientState.VerifyPacketAcknowledgement(
suite.store, suite.cdc, clientHeight, nil, []byte{}, testPortID, testChannelID, testSequence, tc.ack, suite.store, suite.cdc, clientHeight, 0, 0, nil, []byte{}, testPortID, testChannelID, testSequence, tc.ack,
) )
if tc.expPass { if tc.expPass {
@ -411,7 +444,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketReceiptAbsence() {
clientState := types.NewClientState("chainID", clientHeight) clientState := types.NewClientState("chainID", clientHeight)
err := clientState.VerifyPacketReceiptAbsence( err := clientState.VerifyPacketReceiptAbsence(
suite.store, suite.cdc, clientHeight, nil, nil, testPortID, testChannelID, testSequence, suite.store, suite.cdc, clientHeight, 0, 0, nil, nil, testPortID, testChannelID, testSequence,
) )
suite.Require().NoError(err, "receipt absence failed") suite.Require().NoError(err, "receipt absence failed")
@ -419,7 +452,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketReceiptAbsence() {
suite.store.Set(host.PacketReceiptKey(testPortID, testChannelID, testSequence), []byte("receipt")) suite.store.Set(host.PacketReceiptKey(testPortID, testChannelID, testSequence), []byte("receipt"))
err = clientState.VerifyPacketReceiptAbsence( err = clientState.VerifyPacketReceiptAbsence(
suite.store, suite.cdc, clientHeight, nil, nil, testPortID, testChannelID, testSequence, suite.store, suite.cdc, clientHeight, 0, 0, nil, nil, testPortID, testChannelID, testSequence,
) )
suite.Require().Error(err, "receipt exists in store") suite.Require().Error(err, "receipt exists in store")
} }
@ -475,7 +508,7 @@ func (suite *LocalhostTestSuite) TestVerifyNextSeqRecv() {
tc.malleate() tc.malleate()
err := tc.clientState.VerifyNextSequenceRecv( err := tc.clientState.VerifyNextSequenceRecv(
suite.store, suite.cdc, clientHeight, nil, []byte{}, testPortID, testChannelID, nextSeqRecv, suite.store, suite.cdc, clientHeight, 0, 0, nil, []byte{}, testPortID, testChannelID, nextSeqRecv,
) )
if tc.expPass { if tc.expPass {

View File

@ -44,6 +44,7 @@ const (
TrustingPeriod time.Duration = time.Hour * 24 * 7 * 2 TrustingPeriod time.Duration = time.Hour * 24 * 7 * 2
UnbondingPeriod time.Duration = time.Hour * 24 * 7 * 3 UnbondingPeriod time.Duration = time.Hour * 24 * 7 * 3
MaxClockDrift time.Duration = time.Second * 10 MaxClockDrift time.Duration = time.Second * 10
DefaultDelayPeriod uint64 = 0
DefaultChannelVersion = ibctransfertypes.Version DefaultChannelVersion = ibctransfertypes.Version
InvalidID = "IDisInvalid" InvalidID = "IDisInvalid"
@ -643,7 +644,7 @@ func (chain *TestChain) ConnectionOpenInit(
msg := connectiontypes.NewMsgConnectionOpenInit( msg := connectiontypes.NewMsgConnectionOpenInit(
connection.ClientID, connection.ClientID,
connection.CounterpartyClientID, connection.CounterpartyClientID,
counterparty.GetPrefix(), DefaultOpenInitVersion, counterparty.GetPrefix(), DefaultOpenInitVersion, DefaultDelayPeriod,
chain.SenderAccount.GetAddress(), chain.SenderAccount.GetAddress(),
) )
return chain.sendMsgs(msg) return chain.sendMsgs(msg)
@ -664,7 +665,7 @@ func (chain *TestChain) ConnectionOpenTry(
msg := connectiontypes.NewMsgConnectionOpenTry( msg := connectiontypes.NewMsgConnectionOpenTry(
"", connection.ClientID, // does not support handshake continuation "", connection.ClientID, // does not support handshake continuation
counterpartyConnection.ID, counterpartyConnection.ClientID, counterpartyConnection.ID, counterpartyConnection.ClientID,
counterpartyClient, counterparty.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, counterpartyClient, counterparty.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, DefaultDelayPeriod,
proofInit, proofClient, proofConsensus, proofInit, proofClient, proofConsensus,
proofHeight, consensusHeight, proofHeight, consensusHeight,
chain.SenderAccount.GetAddress(), chain.SenderAccount.GetAddress(),

View File

@ -18,7 +18,7 @@ import (
var ( var (
ChainIDPrefix = "testchain" ChainIDPrefix = "testchain"
globalStartTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) globalStartTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
timeIncrement = time.Second * 5 TimeIncrement = time.Second * 5
) )
// Coordinator is a testing struct which contains N TestChain's. It handles keeping all chains // Coordinator is a testing struct which contains N TestChain's. It handles keeping all chains
@ -241,6 +241,10 @@ func (coord *Coordinator) RecvPacket(
packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence())
proof, proofHeight := source.QueryProof(packetKey) proof, proofHeight := source.QueryProof(packetKey)
// Increment time and commit block so that 5 second delay period passes between send and receive
coord.IncrementTime()
coord.CommitBlock(source, counterparty)
recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, counterparty.SenderAccount.GetAddress()) recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, counterparty.SenderAccount.GetAddress())
// receive on counterparty and update source client // receive on counterparty and update source client
@ -280,6 +284,10 @@ func (coord *Coordinator) AcknowledgePacket(
packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
proof, proofHeight := counterparty.QueryProof(packetKey) proof, proofHeight := counterparty.QueryProof(packetKey)
// Increment time and commit block so that 5 second delay period passes between send and receive
coord.IncrementTime()
coord.CommitBlock(source, counterparty)
ackMsg := channeltypes.NewMsgAcknowledgement(packet, ack, proof, proofHeight, source.SenderAccount.GetAddress()) ackMsg := channeltypes.NewMsgAcknowledgement(packet, ack, proof, proofHeight, source.SenderAccount.GetAddress())
return coord.SendMsgs(source, counterparty, counterpartyClient, []sdk.Msg{ackMsg}) return coord.SendMsgs(source, counterparty, counterpartyClient, []sdk.Msg{ackMsg})
} }
@ -291,10 +299,18 @@ func (coord *Coordinator) RelayPacket(
sourceClient, counterpartyClient string, sourceClient, counterpartyClient string,
packet channeltypes.Packet, ack []byte, packet channeltypes.Packet, ack []byte,
) error { ) error {
// Increment time and commit block so that 5 second delay period passes between send and receive
coord.IncrementTime()
coord.CommitBlock(counterparty)
if err := coord.RecvPacket(source, counterparty, sourceClient, packet); err != nil { if err := coord.RecvPacket(source, counterparty, sourceClient, packet); err != nil {
return err return err
} }
// Increment time and commit block so that 5 second delay period passes between send and receive
coord.IncrementTime()
coord.CommitBlock(source)
return coord.AcknowledgePacket(source, counterparty, counterpartyClient, packet, ack) return coord.AcknowledgePacket(source, counterparty, counterpartyClient, packet, ack)
} }
@ -304,7 +320,16 @@ func (coord *Coordinator) RelayPacket(
// CONTRACT: this function must be called after every commit on any TestChain. // CONTRACT: this function must be called after every commit on any TestChain.
func (coord *Coordinator) IncrementTime() { func (coord *Coordinator) IncrementTime() {
for _, chain := range coord.Chains { for _, chain := range coord.Chains {
chain.CurrentHeader.Time = chain.CurrentHeader.Time.Add(timeIncrement) chain.CurrentHeader.Time = chain.CurrentHeader.Time.Add(TimeIncrement)
chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader})
}
}
// IncrementTimeBy iterates through all the TestChain's and increments their current header time
// by specified time.
func (coord *Coordinator) IncrementTimeBy(increment time.Duration) {
for _, chain := range coord.Chains {
chain.CurrentHeader.Time = chain.CurrentHeader.Time.Add(increment)
chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader})
} }
} }