diff --git a/CHANGELOG.md b/CHANGELOG.md index fa14d36630a..71629f83a02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -115,6 +115,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +* (core/02-client) [\#2819](https://github.com/cosmos/ibc-go/pull/2819) Add automatic in-place store migrations to remove the localhost client and migrate existing solo machine definitions. * (light-clients/06-solomachine) [\#2826](https://github.com/cosmos/ibc-go/pull/2826) Add `AppModuleBasic` for the 06-solomachine client and remove solo machine type registration from core IBC. Chains must register the `AppModuleBasic` of light clients. * (light-clients/07-tendermint) [\#2825](https://github.com/cosmos/ibc-go/pull/2825) Add `AppModuleBasic` for the 07-tendermint client and remove tendermint type registration from core IBC. Chains must register the `AppModuleBasic` of light clients. * (light-clients/07-tendermint) [\#2800](https://github.com/cosmos/ibc-go/pull/2800) Add optional in-place store migration function to prune all expired tendermint consensus states. diff --git a/modules/core/02-client/keeper/migrations.go b/modules/core/02-client/keeper/migrations.go index 0bf8cbd1875..c63a6762f5b 100644 --- a/modules/core/02-client/keeper/migrations.go +++ b/modules/core/02-client/keeper/migrations.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" v100 "github.com/cosmos/ibc-go/v6/modules/core/02-client/legacy/v100" + v7 "github.com/cosmos/ibc-go/v6/modules/core/02-client/migrations/v7" ) // Migrator is a struct for handling in-place store migrations. @@ -25,3 +26,13 @@ func NewMigrator(keeper Keeper) Migrator { func (m Migrator) Migrate1to2(ctx sdk.Context) error { return v100.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) } + +// Migrate2to3 migrates from version 2 to 3. +// This migration +// - migrates solo machine client states from v2 to v3 protobuf definition +// - prunes solo machine consensus states +// - removes the localhost client +// - asserts that existing tendermint clients are properly registered on the chain codec +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + return v7.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +} diff --git a/modules/core/02-client/migrations/v7/solomachine.go b/modules/core/02-client/migrations/v7/solomachine.go new file mode 100644 index 00000000000..e28d03a87d7 --- /dev/null +++ b/modules/core/02-client/migrations/v7/solomachine.go @@ -0,0 +1,264 @@ +package v7 + +import ( + ics23 "github.com/confio/ics23/go" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v6/modules/core/exported" +) + +// NOTE: this is a mock implmentation for exported.ClientState. This implementation +// should only be registered on the InterfaceRegistry during cli command genesis migration. +// This implementation is only used to successfully unmarshal the previous solo machine +// client state and consensus state and migrate them to the new implementations. When the proto +// codec unmarshals, it calls UnpackInterfaces() to create a cached value of the any. The +// UnpackInterfaces function for IdenitifiedClientState will attempt to unpack the any to +// exported.ClientState. If the solomachine v2 type is not registered against the exported.ClientState +// the unmarshal will fail. This implementation will panic on every interface function. +// The same is done for the ConsensusState. + +// Interface implementation checks. +var ( + _, _ codectypes.UnpackInterfacesMessage = &ClientState{}, &ConsensusState{} + _ exported.ClientState = (*ClientState)(nil) + _ exported.ConsensusState = &ConsensusState{} +) + +// RegisterInterfaces registers the solomachine v2 ClientState and ConsensusState types in the interface registry. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*exported.ClientState)(nil), + &ClientState{}, + ) + registry.RegisterImplementations( + (*exported.ConsensusState)(nil), + &ConsensusState{}, + ) +} + +// UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method +func (cs ClientState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + return cs.ConsensusState.UnpackInterfaces(unpacker) +} + +// UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method +func (cs ConsensusState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + return unpacker.UnpackAny(cs.PublicKey, new(cryptotypes.PubKey)) +} + +// ClientType panics! +func (cs ClientState) ClientType() string { + panic("legacy solo machine is deprecated!") +} + +// GetLatestHeight panics! +func (cs ClientState) GetLatestHeight() exported.Height { + panic("legacy solo machine is deprecated!") +} + +// Status panics! +func (cs ClientState) Status(_ sdk.Context, _ sdk.KVStore, _ codec.BinaryCodec) exported.Status { + panic("legacy solo machine is deprecated!") +} + +// Validate panics! +func (cs ClientState) Validate() error { + panic("legacy solo machine is deprecated!") +} + +// GetProofSpecs panics! +func (cs ClientState) GetProofSpecs() []*ics23.ProofSpec { + panic("legacy solo machine is deprecated!") +} + +// ZeroCustomFields panics! +func (cs ClientState) ZeroCustomFields() exported.ClientState { + panic("legacy solo machine is deprecated!") +} + +// Initialize panics! +func (cs ClientState) Initialize(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, consState exported.ConsensusState) error { + panic("legacy solo machine is deprecated!") +} + +// ExportMetadata panics! +func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata { + panic("legacy solo machine is deprecated!") +} + +// CheckForMisbehaviour panics! +func (cs ClientState) CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, msg exported.ClientMessage) bool { + panic("legacy solo machine is deprecated!") +} + +// UpdateStateOnMisbehaviour panics! +func (cs *ClientState) UpdateStateOnMisbehaviour( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, +) { + panic("legacy solo machine is deprecated!") +} + +// VerifyClientMessage panics! +func (cs *ClientState) VerifyClientMessage( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, +) error { + panic("legacy solo machine is deprecated!") +} + +// UpdateState panis! +func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) []exported.Height { + panic("legacy solo machine is deprecated!") +} + +// CheckHeaderAndUpdateState panics! +func (cs *ClientState) CheckHeaderAndUpdateState( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, +) (exported.ClientState, exported.ConsensusState, error) { + panic("legacy solo machine is deprecated!") +} + +// CheckMisbehaviourAndUpdateState panics! +func (cs ClientState) CheckMisbehaviourAndUpdateState( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, +) (exported.ClientState, error) { + panic("legacy solo machine is deprecated!") +} + +// CheckSubstituteAndUpdateState panics! +func (cs ClientState) CheckSubstituteAndUpdateState( + ctx sdk.Context, _ codec.BinaryCodec, _, _ sdk.KVStore, + _ exported.ClientState, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyUpgradeAndUpdateState panics! +func (cs ClientState) VerifyUpgradeAndUpdateState( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, + _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyClientState panics! +func (cs ClientState) VerifyClientState( + store sdk.KVStore, cdc codec.BinaryCodec, + _ exported.Height, _ exported.Prefix, _ string, _ []byte, clientState exported.ClientState, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyClientConsensusState panics! +func (cs ClientState) VerifyClientConsensusState( + sdk.KVStore, codec.BinaryCodec, + exported.Height, string, exported.Height, exported.Prefix, + []byte, exported.ConsensusState, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyConnectionState panics! +func (cs ClientState) VerifyConnectionState( + sdk.KVStore, codec.BinaryCodec, exported.Height, + exported.Prefix, []byte, string, exported.ConnectionI, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyChannelState panics! +func (cs ClientState) VerifyChannelState( + sdk.KVStore, codec.BinaryCodec, exported.Height, exported.Prefix, + []byte, string, string, exported.ChannelI, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyPacketCommitment panics! +func (cs ClientState) VerifyPacketCommitment( + sdk.Context, sdk.KVStore, codec.BinaryCodec, exported.Height, + uint64, uint64, exported.Prefix, []byte, + string, string, uint64, []byte, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyPacketAcknowledgement panics! +func (cs ClientState) VerifyPacketAcknowledgement( + sdk.Context, sdk.KVStore, codec.BinaryCodec, exported.Height, + uint64, uint64, exported.Prefix, []byte, + string, string, uint64, []byte, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyPacketReceiptAbsence panics! +func (cs ClientState) VerifyPacketReceiptAbsence( + sdk.Context, sdk.KVStore, codec.BinaryCodec, exported.Height, + uint64, uint64, exported.Prefix, []byte, + string, string, uint64, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyNextSequenceRecv panics! +func (cs ClientState) VerifyNextSequenceRecv( + sdk.Context, sdk.KVStore, codec.BinaryCodec, exported.Height, + uint64, uint64, exported.Prefix, []byte, + string, string, uint64, +) error { + panic("legacy solo machine is deprecated!") +} + +// GetTimestampAtHeight panics! +func (cs ClientState) GetTimestampAtHeight( + sdk.Context, sdk.KVStore, codec.BinaryCodec, exported.Height, +) (uint64, error) { + panic("legacy solo machine is deprecated!") +} + +// VerifyMembership panics! +func (cs *ClientState) VerifyMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, + value []byte, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyNonMembership panics! +func (cs *ClientState) VerifyNonMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, +) error { + panic("legacy solo machine is deprecated") +} + +// ClientType panics! +func (ConsensusState) ClientType() string { + panic("legacy solo machine is deprecated!") +} + +// GetTimestamp panics! +func (cs ConsensusState) GetTimestamp() uint64 { + panic("legacy solo machine is deprecated!") +} + +// ValidateBasic panics! +func (cs ConsensusState) ValidateBasic() error { + panic("legacy solo machine is deprecated!") +} diff --git a/modules/core/02-client/migrations/v6/solomachine.pb.go b/modules/core/02-client/migrations/v7/solomachine.pb.go similarity index 92% rename from modules/core/02-client/migrations/v6/solomachine.pb.go rename to modules/core/02-client/migrations/v7/solomachine.pb.go index 573b0b577b9..bd6d9d61657 100644 --- a/modules/core/02-client/migrations/v6/solomachine.pb.go +++ b/modules/core/02-client/migrations/v7/solomachine.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: ibc/lightclients/solomachine/v2/solomachine.proto -package v6 +package v7 import ( fmt "fmt" @@ -823,93 +823,93 @@ func init() { } var fileDescriptor_141333b361aae010 = []byte{ - // 1374 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xdf, 0x8e, 0xdb, 0x44, - 0x17, 0x5f, 0xa7, 0xe9, 0x76, 0x33, 0xd9, 0xee, 0xe6, 0x73, 0xd3, 0x36, 0xeb, 0x56, 0x89, 0x3f, - 0x23, 0xca, 0x82, 0x68, 0xcc, 0x2e, 0x62, 0x85, 0x2a, 0x04, 0x75, 0x1c, 0x97, 0xa6, 0xdd, 0xf5, - 0x06, 0xc7, 0x0b, 0xb4, 0x42, 0xb2, 0x1c, 0x7b, 0x36, 0xb1, 0x9a, 0x78, 0xd2, 0x78, 0x92, 0x34, - 0x48, 0x48, 0x88, 0xab, 0x12, 0x71, 0xc1, 0x0b, 0x44, 0x42, 0x20, 0x9e, 0x83, 0x3b, 0xe0, 0xb2, - 0x97, 0x5c, 0x05, 0xd4, 0xbe, 0x41, 0x9e, 0x00, 0xd9, 0x33, 0x89, 0xed, 0x6c, 0x37, 0x2b, 0xfe, - 0xdd, 0xcd, 0x9c, 0xdf, 0x39, 0xbf, 0x73, 0xe6, 0x9c, 0xe3, 0x33, 0x63, 0xb0, 0xe3, 0xd4, 0x2d, - 0xb1, 0xe5, 0x34, 0x9a, 0xd8, 0x6a, 0x39, 0xd0, 0xc5, 0x9e, 0xe8, 0xa1, 0x16, 0x6a, 0x9b, 0x56, - 0xd3, 0x71, 0xa1, 0xd8, 0xdf, 0x8d, 0x6e, 0x8b, 0x9d, 0x2e, 0xc2, 0x88, 0x2d, 0x38, 0x75, 0xab, - 0x18, 0x35, 0x29, 0x46, 0x75, 0xfa, 0xbb, 0xdc, 0x6b, 0x3e, 0xa7, 0x85, 0xba, 0x50, 0xb4, 0x90, - 0xeb, 0x42, 0x0b, 0x3b, 0xc8, 0x15, 0xfb, 0x3b, 0x91, 0x1d, 0x61, 0xe2, 0xfe, 0x1f, 0x2a, 0x36, - 0x4d, 0xd7, 0x85, 0xad, 0x40, 0x8b, 0x2c, 0xa9, 0x4a, 0xb6, 0x81, 0x1a, 0x28, 0x58, 0x8a, 0xfe, - 0x8a, 0x4a, 0xb7, 0x1a, 0x08, 0x35, 0x5a, 0x50, 0x0c, 0x76, 0xf5, 0xde, 0xb1, 0x68, 0xba, 0x43, - 0x02, 0x09, 0x3f, 0x25, 0x40, 0x5a, 0x0e, 0xe2, 0xaa, 0x61, 0x13, 0x43, 0x96, 0x03, 0x6b, 0x1e, - 0x7c, 0xdc, 0x83, 0xae, 0x05, 0x73, 0x0c, 0xcf, 0x6c, 0x27, 0xb5, 0xf9, 0x9e, 0xdd, 0x01, 0x29, - 0xc7, 0x33, 0x8e, 0xbb, 0xe8, 0x73, 0xe8, 0xe6, 0x12, 0x3c, 0xb3, 0xbd, 0x56, 0xca, 0x4e, 0x27, - 0x85, 0xcc, 0xd0, 0x6c, 0xb7, 0x6e, 0x09, 0x73, 0x48, 0xd0, 0xd6, 0x1c, 0xef, 0x4e, 0xb0, 0x64, - 0x31, 0xd8, 0xb4, 0x90, 0xeb, 0x41, 0xd7, 0xeb, 0x79, 0x86, 0xe7, 0x7b, 0xc8, 0x9d, 0xe3, 0x99, - 0xed, 0xf4, 0xae, 0x58, 0x3c, 0x23, 0x2d, 0x45, 0x79, 0x66, 0x17, 0x04, 0x56, 0xe2, 0xa6, 0x93, - 0xc2, 0x15, 0xe2, 0x69, 0x81, 0x51, 0xd0, 0x36, 0xac, 0x98, 0x2e, 0x0b, 0xc1, 0x35, 0xb3, 0xd5, - 0x42, 0x03, 0xa3, 0xd7, 0xb1, 0x4d, 0x0c, 0x0d, 0xf3, 0x18, 0xc3, 0xae, 0xd1, 0xe9, 0xa2, 0x0e, - 0xf2, 0xcc, 0x56, 0x2e, 0x19, 0x84, 0x7e, 0x63, 0x3a, 0x29, 0x08, 0x84, 0x70, 0x89, 0xb2, 0xa0, - 0xe5, 0x02, 0xf4, 0x28, 0x00, 0x25, 0x1f, 0xab, 0x52, 0xe8, 0x56, 0xf2, 0xe9, 0x77, 0x85, 0x15, - 0xe1, 0x7b, 0x06, 0x6c, 0xc4, 0x63, 0x65, 0xef, 0x01, 0xd0, 0xe9, 0xd5, 0x5b, 0x8e, 0x65, 0x3c, - 0x82, 0xc3, 0x20, 0x8d, 0xe9, 0xdd, 0x6c, 0x91, 0x14, 0xa1, 0x38, 0x2b, 0x42, 0x51, 0x72, 0x87, - 0xa5, 0xcb, 0xd3, 0x49, 0xe1, 0x7f, 0x24, 0x88, 0xd0, 0x42, 0xd0, 0x52, 0x64, 0x73, 0x1f, 0x0e, - 0x59, 0x1e, 0xa4, 0x6d, 0xa7, 0x0f, 0xbb, 0x9e, 0x73, 0xec, 0xc0, 0x6e, 0x90, 0xf6, 0x94, 0x16, - 0x15, 0xb1, 0xd7, 0x41, 0x0a, 0x3b, 0x6d, 0xe8, 0x61, 0xb3, 0xdd, 0x09, 0xb2, 0x9b, 0xd4, 0x42, - 0x01, 0x0d, 0xf2, 0xab, 0x04, 0x58, 0xbd, 0x0b, 0x4d, 0x1b, 0x76, 0x97, 0x56, 0x38, 0x46, 0x95, - 0x58, 0xa0, 0xf2, 0x51, 0xcf, 0x69, 0xb8, 0x26, 0xee, 0x75, 0x49, 0x19, 0xd7, 0xb5, 0x50, 0xc0, - 0x1e, 0x81, 0x0d, 0x17, 0x0e, 0x8c, 0xc8, 0xc1, 0x93, 0x4b, 0x0e, 0xbe, 0x35, 0x9d, 0x14, 0x2e, - 0x93, 0x83, 0xc7, 0xad, 0x04, 0x6d, 0xdd, 0x85, 0x83, 0xea, 0xfc, 0xfc, 0x32, 0xd8, 0xf4, 0x15, - 0xa2, 0x39, 0x38, 0xef, 0xe7, 0x20, 0xda, 0x10, 0x0b, 0x0a, 0x82, 0xe6, 0x47, 0x52, 0x0e, 0x05, - 0x34, 0x09, 0xbf, 0x24, 0xc0, 0xfa, 0x81, 0xe3, 0xd5, 0x61, 0xd3, 0xec, 0x3b, 0xa8, 0xd7, 0xf5, - 0x1b, 0x9a, 0x34, 0x9f, 0xe1, 0xd8, 0x41, 0x2e, 0x52, 0xd1, 0x86, 0x9e, 0x43, 0x82, 0xb6, 0x46, - 0xd6, 0x15, 0x3b, 0x96, 0xbd, 0xc4, 0x42, 0xf6, 0x3a, 0xe0, 0xe2, 0x3c, 0x1d, 0x06, 0x72, 0x67, - 0xad, 0xbe, 0x73, 0x66, 0xab, 0xd7, 0x66, 0x56, 0x92, 0x6b, 0x97, 0x4d, 0x6c, 0x96, 0x72, 0xd3, - 0x49, 0x21, 0x4b, 0xa2, 0x88, 0x31, 0x0a, 0xda, 0xfa, 0x7c, 0x7f, 0xe8, 0x2e, 0x78, 0xc4, 0x03, - 0x44, 0x53, 0xfe, 0x6f, 0x79, 0xc4, 0x03, 0x14, 0xf5, 0xa8, 0x0f, 0x10, 0xcd, 0xe4, 0xcf, 0x0c, - 0xc8, 0x2c, 0x52, 0xc4, 0xdb, 0x83, 0x59, 0x6c, 0x8f, 0xcf, 0x40, 0xca, 0x36, 0xb1, 0x69, 0xe0, - 0x61, 0x87, 0x64, 0x6e, 0x63, 0xf7, 0xf5, 0x33, 0xc3, 0xf4, 0x79, 0xf5, 0x61, 0x07, 0x46, 0xcb, - 0x32, 0x67, 0x11, 0xb4, 0x35, 0x9b, 0xe2, 0x2c, 0x0b, 0x92, 0xfe, 0x9a, 0x76, 0x65, 0xb0, 0x8e, - 0x37, 0x73, 0xf2, 0xe5, 0xdf, 0xc5, 0x97, 0x0c, 0xc8, 0xe9, 0x33, 0x19, 0xb4, 0xe7, 0x67, 0x0a, - 0x0e, 0x74, 0x1b, 0x6c, 0x84, 0xb9, 0x08, 0xe8, 0x83, 0x53, 0x45, 0x7b, 0x37, 0x8e, 0x0b, 0x5a, - 0x58, 0x8e, 0xf2, 0x89, 0x10, 0x12, 0x2f, 0x0f, 0xe1, 0x77, 0x06, 0xa4, 0x7c, 0xbf, 0xa5, 0x21, - 0x86, 0xde, 0x3f, 0xf8, 0x3a, 0x17, 0x06, 0xc5, 0xb9, 0x93, 0x83, 0x22, 0x56, 0x82, 0xe4, 0x7f, - 0x55, 0x82, 0xf3, 0x61, 0x09, 0xe8, 0x09, 0x7f, 0x64, 0x00, 0x20, 0xc3, 0x27, 0x48, 0xca, 0x3e, - 0x48, 0xd3, 0x4f, 0xfe, 0xcc, 0xf1, 0x78, 0x65, 0x3a, 0x29, 0xb0, 0xb1, 0x29, 0x41, 0xe7, 0x23, - 0x19, 0x11, 0xa7, 0xcc, 0x87, 0xc4, 0xdf, 0x9c, 0x0f, 0x5f, 0x80, 0xcd, 0xc8, 0x55, 0x18, 0xc4, - 0xca, 0x82, 0x64, 0xc7, 0xc4, 0x4d, 0xda, 0xce, 0xc1, 0x9a, 0xad, 0x82, 0x75, 0x3a, 0x1a, 0xc8, - 0x85, 0x96, 0x58, 0x72, 0x80, 0xab, 0xd3, 0x49, 0xe1, 0x52, 0x6c, 0x9c, 0xd0, 0x2b, 0x2b, 0x6d, - 0x85, 0x9e, 0xa8, 0xfb, 0xaf, 0x19, 0xc0, 0xc6, 0x2f, 0x92, 0x53, 0x43, 0x78, 0x70, 0xf2, 0x5a, - 0x5d, 0x16, 0xc5, 0x5f, 0xb8, 0x3b, 0x69, 0x2c, 0x7d, 0x70, 0x49, 0x9e, 0x3f, 0x3f, 0x96, 0xc7, - 0xa2, 0x00, 0x10, 0xbe, 0x54, 0x68, 0x18, 0xaf, 0x06, 0x6d, 0xe5, 0x3f, 0x55, 0x8a, 0x91, 0x57, - 0x4c, 0x7f, 0xa7, 0x18, 0x92, 0x2a, 0xae, 0xad, 0x45, 0x0c, 0xa9, 0x5f, 0x1b, 0x64, 0x64, 0xf2, - 0xa0, 0x59, 0xee, 0x74, 0x0f, 0x5c, 0xa0, 0x0f, 0x1f, 0xea, 0xf1, 0x7a, 0xc4, 0x23, 0x7d, 0x11, - 0xf9, 0xee, 0xc8, 0x52, 0x9b, 0x29, 0x53, 0x2f, 0xf7, 0x40, 0xb6, 0x6a, 0x5a, 0x8f, 0x20, 0x96, - 0x51, 0xbb, 0xed, 0xe0, 0x36, 0x74, 0xf1, 0xa9, 0x9e, 0xf2, 0xfe, 0xf1, 0x66, 0x5a, 0x81, 0xb3, - 0x75, 0x2d, 0x22, 0x11, 0x1e, 0x80, 0x2d, 0xc2, 0x25, 0x59, 0x8f, 0x5c, 0x34, 0x68, 0x41, 0xbb, - 0x01, 0x97, 0x12, 0x6e, 0x83, 0x4d, 0x33, 0xae, 0x4a, 0x59, 0x17, 0xc5, 0x42, 0x11, 0xe4, 0x08, - 0xb5, 0x06, 0x2d, 0xe8, 0x74, 0xb0, 0x54, 0xf7, 0xfc, 0x39, 0x70, 0x1a, 0xb3, 0xd0, 0x04, 0x59, - 0x15, 0x3e, 0xc1, 0x35, 0x3a, 0x2f, 0x34, 0x68, 0xf5, 0x4f, 0x8d, 0xe2, 0x3d, 0x70, 0xd1, 0x85, - 0x4f, 0xb0, 0xe1, 0xc1, 0xc7, 0x46, 0x17, 0x5a, 0x7d, 0x32, 0x4f, 0xa2, 0xd7, 0x40, 0x0c, 0x16, - 0xb4, 0xb4, 0x4b, 0xa8, 0x7d, 0xd6, 0x37, 0xbe, 0x49, 0x82, 0xb5, 0xd9, 0x60, 0x60, 0xdf, 0x05, - 0xaf, 0x94, 0x25, 0x5d, 0x32, 0xf4, 0x07, 0x55, 0xc5, 0x38, 0x52, 0x2b, 0x6a, 0x45, 0xaf, 0x48, - 0xfb, 0x95, 0x87, 0x4a, 0xd9, 0x38, 0x52, 0x6b, 0x55, 0x45, 0xae, 0xdc, 0xa9, 0x28, 0xe5, 0xcc, - 0x0a, 0xb7, 0x39, 0x1a, 0xf3, 0xe9, 0x88, 0x88, 0xbd, 0x01, 0xae, 0x84, 0x96, 0xf2, 0x7e, 0x45, - 0x51, 0x75, 0xa3, 0xa6, 0x4b, 0xba, 0x92, 0x61, 0x38, 0x30, 0x1a, 0xf3, 0xab, 0x44, 0xc6, 0xbe, - 0x09, 0xb6, 0x22, 0x7a, 0x87, 0x6a, 0x4d, 0x51, 0x6b, 0x47, 0x35, 0xaa, 0x9a, 0xe0, 0x2e, 0x8e, - 0xc6, 0x7c, 0x6a, 0x2e, 0x66, 0x8b, 0x80, 0x8b, 0x69, 0xab, 0x8a, 0xac, 0x57, 0x0e, 0x55, 0xaa, - 0x7e, 0x8e, 0xdb, 0x18, 0x8d, 0x79, 0x10, 0xca, 0xd9, 0x6d, 0x70, 0x35, 0xa2, 0x7f, 0x57, 0x52, - 0x55, 0x65, 0x9f, 0x2a, 0x27, 0xb9, 0xf4, 0x68, 0xcc, 0x5f, 0xa0, 0x42, 0xf6, 0x1d, 0x70, 0x2d, - 0xd4, 0xac, 0x4a, 0xf2, 0x7d, 0x45, 0x37, 0xe4, 0xc3, 0x83, 0x83, 0x8a, 0x7e, 0xa0, 0xa8, 0x7a, - 0xe6, 0x3c, 0x97, 0x1d, 0x8d, 0xf9, 0x0c, 0x01, 0x42, 0x39, 0xfb, 0x01, 0xe0, 0x4f, 0x98, 0x49, - 0xf2, 0x7d, 0xf5, 0xf0, 0x93, 0x7d, 0xa5, 0xfc, 0xa1, 0x12, 0xd8, 0xae, 0x72, 0x5b, 0xa3, 0x31, - 0x7f, 0x99, 0xa0, 0x0b, 0x20, 0xfb, 0xfe, 0x4b, 0x08, 0x34, 0x45, 0x56, 0x2a, 0x55, 0xdd, 0x90, - 0x4a, 0x35, 0x45, 0x95, 0x95, 0xcc, 0x05, 0x2e, 0x37, 0x1a, 0xf3, 0x59, 0x82, 0x52, 0x90, 0x62, - 0xec, 0x1e, 0xb8, 0x1e, 0xda, 0xab, 0xca, 0xa7, 0xba, 0x51, 0x53, 0x3e, 0x3a, 0xf2, 0x21, 0x9f, - 0xe6, 0xe3, 0xcc, 0x1a, 0x09, 0xdc, 0x47, 0x66, 0x80, 0x2f, 0x67, 0x79, 0x90, 0x09, 0xed, 0xee, - 0x2a, 0x52, 0x59, 0xd1, 0x32, 0x29, 0x52, 0x19, 0xb2, 0xe3, 0x92, 0x4f, 0x7f, 0xc8, 0xaf, 0x94, - 0x1e, 0xfe, 0xfa, 0x3c, 0xcf, 0x3c, 0x7b, 0x9e, 0x67, 0xfe, 0x78, 0x9e, 0x67, 0xbe, 0x7d, 0x91, - 0x5f, 0x79, 0xf6, 0x22, 0xbf, 0xf2, 0xdb, 0x8b, 0xfc, 0xca, 0xc3, 0xdb, 0x0d, 0x07, 0x37, 0x7b, - 0xf5, 0xa2, 0x85, 0xda, 0xa2, 0x85, 0xbc, 0x36, 0xf2, 0x44, 0xa7, 0x6e, 0xdd, 0x6c, 0x20, 0xb1, - 0xbf, 0x27, 0xb6, 0x91, 0xdd, 0x6b, 0x41, 0x8f, 0xfc, 0xd2, 0xbc, 0xb5, 0x7b, 0x93, 0x8c, 0x44, - 0xb1, 0xed, 0x34, 0xba, 0xa6, 0x3f, 0x13, 0x3c, 0xb1, 0xbf, 0x57, 0x5f, 0x0d, 0x26, 0xd9, 0xdb, - 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0x29, 0x02, 0x33, 0x3e, 0x7a, 0x0d, 0x00, 0x00, + // 1373 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x5f, 0x8f, 0xdb, 0x44, + 0x10, 0x3f, 0xa7, 0xe9, 0xf5, 0xb2, 0xb9, 0xde, 0x05, 0x37, 0x6d, 0x73, 0x6e, 0x95, 0x18, 0x23, + 0xca, 0x81, 0x68, 0xcc, 0x1d, 0xa2, 0xa0, 0x0a, 0x41, 0x1d, 0xc7, 0xa5, 0x69, 0xef, 0x7c, 0xc1, + 0xf1, 0x01, 0xad, 0x90, 0x2c, 0xc7, 0xde, 0x4b, 0xac, 0x26, 0xde, 0x34, 0xde, 0x24, 0x0d, 0x12, + 0x12, 0xe2, 0xa9, 0x44, 0x3c, 0xf0, 0x05, 0x22, 0x21, 0x10, 0x9f, 0x83, 0x37, 0xe0, 0xb1, 0x8f, + 0x3c, 0x05, 0xd4, 0x7e, 0x83, 0x7c, 0x02, 0x64, 0xef, 0x26, 0xb6, 0x73, 0xbd, 0x9c, 0xf8, 0xf7, + 0xb6, 0x3b, 0xbf, 0x99, 0xdf, 0xcc, 0xce, 0x8c, 0x67, 0xd7, 0x60, 0xc7, 0xa9, 0x5b, 0x62, 0xcb, + 0x69, 0x34, 0xb1, 0xd5, 0x72, 0xa0, 0x8b, 0x3d, 0xd1, 0x43, 0x2d, 0xd4, 0x36, 0xad, 0xa6, 0xe3, + 0x42, 0xb1, 0xbf, 0x1b, 0xdd, 0x16, 0x3b, 0x5d, 0x84, 0x11, 0x5b, 0x70, 0xea, 0x56, 0x31, 0x6a, + 0x52, 0x8c, 0xea, 0xf4, 0x77, 0xb9, 0xd7, 0x7c, 0x4e, 0x0b, 0x75, 0xa1, 0x68, 0x21, 0xd7, 0x85, + 0x16, 0x76, 0x90, 0x2b, 0xf6, 0x77, 0x22, 0x3b, 0xc2, 0xc4, 0xbd, 0x1c, 0x2a, 0x36, 0x4d, 0xd7, + 0x85, 0xad, 0x40, 0x8b, 0x2c, 0xa9, 0x4a, 0xb6, 0x81, 0x1a, 0x28, 0x58, 0x8a, 0xfe, 0x8a, 0x4a, + 0xb7, 0x1a, 0x08, 0x35, 0x5a, 0x50, 0x0c, 0x76, 0xf5, 0xde, 0x91, 0x68, 0xba, 0x43, 0x02, 0x09, + 0x3f, 0x27, 0x40, 0x5a, 0x0e, 0xe2, 0xaa, 0x61, 0x13, 0x43, 0x96, 0x03, 0x6b, 0x1e, 0x7c, 0xd4, + 0x83, 0xae, 0x05, 0x73, 0x0c, 0xcf, 0x6c, 0x27, 0xb5, 0xf9, 0x9e, 0xdd, 0x01, 0x29, 0xc7, 0x33, + 0x8e, 0xba, 0xe8, 0x0b, 0xe8, 0xe6, 0x12, 0x3c, 0xb3, 0xbd, 0x56, 0xca, 0x4e, 0x27, 0x85, 0xcc, + 0xd0, 0x6c, 0xb7, 0x6e, 0x0a, 0x73, 0x48, 0xd0, 0xd6, 0x1c, 0xef, 0x76, 0xb0, 0x64, 0x31, 0xd8, + 0xb4, 0x90, 0xeb, 0x41, 0xd7, 0xeb, 0x79, 0x86, 0xe7, 0x7b, 0xc8, 0x9d, 0xe1, 0x99, 0xed, 0xf4, + 0xae, 0x58, 0x3c, 0x25, 0x2d, 0x45, 0x79, 0x66, 0x17, 0x04, 0x56, 0xe2, 0xa6, 0x93, 0xc2, 0x25, + 0xe2, 0x69, 0x81, 0x51, 0xd0, 0x36, 0xac, 0x98, 0x2e, 0x0b, 0xc1, 0x15, 0xb3, 0xd5, 0x42, 0x03, + 0xa3, 0xd7, 0xb1, 0x4d, 0x0c, 0x0d, 0xf3, 0x08, 0xc3, 0xae, 0xd1, 0xe9, 0xa2, 0x0e, 0xf2, 0xcc, + 0x56, 0x2e, 0x19, 0x84, 0x7e, 0x6d, 0x3a, 0x29, 0x08, 0x84, 0x70, 0x89, 0xb2, 0xa0, 0xe5, 0x02, + 0xf4, 0x30, 0x00, 0x25, 0x1f, 0xab, 0x52, 0xe8, 0x66, 0xf2, 0xc9, 0xf7, 0x85, 0x15, 0xe1, 0x07, + 0x06, 0x6c, 0xc4, 0x63, 0x65, 0xef, 0x02, 0xd0, 0xe9, 0xd5, 0x5b, 0x8e, 0x65, 0x3c, 0x84, 0xc3, + 0x20, 0x8d, 0xe9, 0xdd, 0x6c, 0x91, 0x14, 0xa1, 0x38, 0x2b, 0x42, 0x51, 0x72, 0x87, 0xa5, 0x8b, + 0xd3, 0x49, 0xe1, 0x25, 0x12, 0x44, 0x68, 0x21, 0x68, 0x29, 0xb2, 0xb9, 0x07, 0x87, 0x2c, 0x0f, + 0xd2, 0xb6, 0xd3, 0x87, 0x5d, 0xcf, 0x39, 0x72, 0x60, 0x37, 0x48, 0x7b, 0x4a, 0x8b, 0x8a, 0xd8, + 0xab, 0x20, 0x85, 0x9d, 0x36, 0xf4, 0xb0, 0xd9, 0xee, 0x04, 0xd9, 0x4d, 0x6a, 0xa1, 0x80, 0x06, + 0xf9, 0x75, 0x02, 0xac, 0xde, 0x81, 0xa6, 0x0d, 0xbb, 0x4b, 0x2b, 0x1c, 0xa3, 0x4a, 0x2c, 0x50, + 0xf9, 0xa8, 0xe7, 0x34, 0x5c, 0x13, 0xf7, 0xba, 0xa4, 0x8c, 0xeb, 0x5a, 0x28, 0x60, 0x0f, 0xc1, + 0x86, 0x0b, 0x07, 0x46, 0xe4, 0xe0, 0xc9, 0x25, 0x07, 0xdf, 0x9a, 0x4e, 0x0a, 0x17, 0xc9, 0xc1, + 0xe3, 0x56, 0x82, 0xb6, 0xee, 0xc2, 0x41, 0x75, 0x7e, 0x7e, 0x19, 0x6c, 0xfa, 0x0a, 0xd1, 0x1c, + 0x9c, 0xf5, 0x73, 0x10, 0x6d, 0x88, 0x05, 0x05, 0x41, 0xf3, 0x23, 0x29, 0x87, 0x02, 0x9a, 0x84, + 0x5f, 0x13, 0x60, 0x7d, 0xdf, 0xf1, 0xea, 0xb0, 0x69, 0xf6, 0x1d, 0xd4, 0xeb, 0xfa, 0x0d, 0x4d, + 0x9a, 0xcf, 0x70, 0xec, 0x20, 0x17, 0xa9, 0x68, 0x43, 0xcf, 0x21, 0x41, 0x5b, 0x23, 0xeb, 0x8a, + 0x1d, 0xcb, 0x5e, 0x62, 0x21, 0x7b, 0x1d, 0x70, 0x7e, 0x9e, 0x0e, 0x03, 0xb9, 0xb3, 0x56, 0xdf, + 0x39, 0xb5, 0xd5, 0x6b, 0x33, 0x2b, 0xc9, 0xb5, 0xcb, 0x26, 0x36, 0x4b, 0xb9, 0xe9, 0xa4, 0x90, + 0x25, 0x51, 0xc4, 0x18, 0x05, 0x6d, 0x7d, 0xbe, 0x3f, 0x70, 0x17, 0x3c, 0xe2, 0x01, 0xa2, 0x29, + 0xff, 0xaf, 0x3c, 0xe2, 0x01, 0x8a, 0x7a, 0xd4, 0x07, 0x88, 0x66, 0xf2, 0x17, 0x06, 0x64, 0x16, + 0x29, 0xe2, 0xed, 0xc1, 0x2c, 0xb6, 0xc7, 0xe7, 0x20, 0x65, 0x9b, 0xd8, 0x34, 0xf0, 0xb0, 0x43, + 0x32, 0xb7, 0xb1, 0xfb, 0xfa, 0xa9, 0x61, 0xfa, 0xbc, 0xfa, 0xb0, 0x03, 0xa3, 0x65, 0x99, 0xb3, + 0x08, 0xda, 0x9a, 0x4d, 0x71, 0x96, 0x05, 0x49, 0x7f, 0x4d, 0xbb, 0x32, 0x58, 0xc7, 0x9b, 0x39, + 0xf9, 0xe2, 0xef, 0xe2, 0x2b, 0x06, 0xe4, 0xf4, 0x99, 0x0c, 0xda, 0xf3, 0x33, 0x05, 0x07, 0xba, + 0x05, 0x36, 0xc2, 0x5c, 0x04, 0xf4, 0xc1, 0xa9, 0xa2, 0xbd, 0x1b, 0xc7, 0x05, 0x2d, 0x2c, 0x47, + 0xf9, 0x58, 0x08, 0x89, 0x17, 0x87, 0xf0, 0x07, 0x03, 0x52, 0xbe, 0xdf, 0xd2, 0x10, 0x43, 0xef, + 0x5f, 0x7c, 0x9d, 0x0b, 0x83, 0xe2, 0xcc, 0xf1, 0x41, 0x11, 0x2b, 0x41, 0xf2, 0xff, 0x2a, 0xc1, + 0xd9, 0xb0, 0x04, 0xf4, 0x84, 0x3f, 0x31, 0x00, 0x90, 0xe1, 0x13, 0x24, 0x65, 0x0f, 0xa4, 0xe9, + 0x27, 0x7f, 0xea, 0x78, 0xbc, 0x34, 0x9d, 0x14, 0xd8, 0xd8, 0x94, 0xa0, 0xf3, 0x91, 0x8c, 0x88, + 0x13, 0xe6, 0x43, 0xe2, 0x1f, 0xce, 0x87, 0x2f, 0xc1, 0x66, 0xe4, 0x2a, 0x0c, 0x62, 0x65, 0x41, + 0xb2, 0x63, 0xe2, 0x26, 0x6d, 0xe7, 0x60, 0xcd, 0x56, 0xc1, 0x3a, 0x1d, 0x0d, 0xe4, 0x42, 0x4b, + 0x2c, 0x39, 0xc0, 0xe5, 0xe9, 0xa4, 0x70, 0x21, 0x36, 0x4e, 0xe8, 0x95, 0x95, 0xb6, 0x42, 0x4f, + 0xd4, 0xfd, 0x37, 0x0c, 0x60, 0xe3, 0x17, 0xc9, 0x89, 0x21, 0xdc, 0x3f, 0x7e, 0xad, 0x2e, 0x8b, + 0xe2, 0x6f, 0xdc, 0x9d, 0x34, 0x96, 0x3e, 0xb8, 0x20, 0xcf, 0x9f, 0x1f, 0xcb, 0x63, 0x51, 0x00, + 0x08, 0x5f, 0x2a, 0x34, 0x8c, 0x57, 0x83, 0xb6, 0xf2, 0x9f, 0x2a, 0xc5, 0xc8, 0x2b, 0xa6, 0xbf, + 0x53, 0x0c, 0x49, 0x15, 0xd7, 0xd6, 0x22, 0x86, 0xd4, 0xaf, 0x0d, 0x32, 0x32, 0x79, 0xd0, 0x2c, + 0x77, 0x7a, 0x03, 0x9c, 0xa3, 0x0f, 0x1f, 0xea, 0xf1, 0x6a, 0xc4, 0x23, 0x7d, 0x11, 0xf9, 0xee, + 0xc8, 0x52, 0x9b, 0x29, 0x53, 0x2f, 0x77, 0x41, 0xb6, 0x6a, 0x5a, 0x0f, 0x21, 0x96, 0x51, 0xbb, + 0xed, 0xe0, 0x36, 0x74, 0xf1, 0x89, 0x9e, 0xf2, 0xfe, 0xf1, 0x66, 0x5a, 0x81, 0xb3, 0x75, 0x2d, + 0x22, 0x11, 0xee, 0x83, 0x2d, 0xc2, 0x25, 0x59, 0x0f, 0x5d, 0x34, 0x68, 0x41, 0xbb, 0x01, 0x97, + 0x12, 0x6e, 0x83, 0x4d, 0x33, 0xae, 0x4a, 0x59, 0x17, 0xc5, 0x42, 0x11, 0xe4, 0x08, 0xb5, 0x06, + 0x2d, 0xe8, 0x74, 0xb0, 0x54, 0xf7, 0xfc, 0x39, 0x70, 0x12, 0xb3, 0xd0, 0x04, 0x59, 0x15, 0x3e, + 0xc6, 0x35, 0x3a, 0x2f, 0x34, 0x68, 0xf5, 0x4f, 0x8c, 0xe2, 0x7d, 0x70, 0xde, 0x85, 0x8f, 0xb1, + 0xe1, 0xc1, 0x47, 0x46, 0x17, 0x5a, 0x7d, 0x32, 0x4f, 0xa2, 0xd7, 0x40, 0x0c, 0x16, 0xb4, 0xb4, + 0x4b, 0xa8, 0x7d, 0xd6, 0x37, 0xbe, 0x4d, 0x82, 0xb5, 0xd9, 0x60, 0x60, 0xdf, 0x03, 0xaf, 0x94, + 0x25, 0x5d, 0x32, 0xf4, 0xfb, 0x55, 0xc5, 0x38, 0x54, 0x2b, 0x6a, 0x45, 0xaf, 0x48, 0x7b, 0x95, + 0x07, 0x4a, 0xd9, 0x38, 0x54, 0x6b, 0x55, 0x45, 0xae, 0xdc, 0xae, 0x28, 0xe5, 0xcc, 0x0a, 0xb7, + 0x39, 0x1a, 0xf3, 0xe9, 0x88, 0x88, 0xbd, 0x06, 0x2e, 0x85, 0x96, 0xf2, 0x5e, 0x45, 0x51, 0x75, + 0xa3, 0xa6, 0x4b, 0xba, 0x92, 0x61, 0x38, 0x30, 0x1a, 0xf3, 0xab, 0x44, 0xc6, 0xbe, 0x09, 0xb6, + 0x22, 0x7a, 0x07, 0x6a, 0x4d, 0x51, 0x6b, 0x87, 0x35, 0xaa, 0x9a, 0xe0, 0xce, 0x8f, 0xc6, 0x7c, + 0x6a, 0x2e, 0x66, 0x8b, 0x80, 0x8b, 0x69, 0xab, 0x8a, 0xac, 0x57, 0x0e, 0x54, 0xaa, 0x7e, 0x86, + 0xdb, 0x18, 0x8d, 0x79, 0x10, 0xca, 0xd9, 0x6d, 0x70, 0x39, 0xa2, 0x7f, 0x47, 0x52, 0x55, 0x65, + 0x8f, 0x2a, 0x27, 0xb9, 0xf4, 0x68, 0xcc, 0x9f, 0xa3, 0x42, 0xf6, 0x1d, 0x70, 0x25, 0xd4, 0xac, + 0x4a, 0xf2, 0x3d, 0x45, 0x37, 0xe4, 0x83, 0xfd, 0xfd, 0x8a, 0xbe, 0xaf, 0xa8, 0x7a, 0xe6, 0x2c, + 0x97, 0x1d, 0x8d, 0xf9, 0x0c, 0x01, 0x42, 0x39, 0xfb, 0x21, 0xe0, 0x8f, 0x99, 0x49, 0xf2, 0x3d, + 0xf5, 0xe0, 0xd3, 0x3d, 0xa5, 0xfc, 0x91, 0x12, 0xd8, 0xae, 0x72, 0x5b, 0xa3, 0x31, 0x7f, 0x91, + 0xa0, 0x0b, 0x20, 0xfb, 0xc1, 0x0b, 0x08, 0x34, 0x45, 0x56, 0x2a, 0x55, 0xdd, 0x90, 0x4a, 0x35, + 0x45, 0x95, 0x95, 0xcc, 0x39, 0x2e, 0x37, 0x1a, 0xf3, 0x59, 0x82, 0x52, 0x90, 0x62, 0xec, 0x0d, + 0x70, 0x35, 0xb4, 0x57, 0x95, 0xcf, 0x74, 0xa3, 0xa6, 0x7c, 0x7c, 0xe8, 0x43, 0x3e, 0xcd, 0x27, + 0x99, 0x35, 0x12, 0xb8, 0x8f, 0xcc, 0x00, 0x5f, 0xce, 0xf2, 0x20, 0x13, 0xda, 0xdd, 0x51, 0xa4, + 0xb2, 0xa2, 0x65, 0x52, 0xa4, 0x32, 0x64, 0xc7, 0x25, 0x9f, 0xfc, 0x98, 0x5f, 0x29, 0x3d, 0xf8, + 0xed, 0x59, 0x9e, 0x79, 0xfa, 0x2c, 0xcf, 0xfc, 0xf9, 0x2c, 0xcf, 0x7c, 0xf7, 0x3c, 0xbf, 0xf2, + 0xf4, 0x79, 0x7e, 0xe5, 0xf7, 0xe7, 0xf9, 0x95, 0x07, 0xb7, 0x1a, 0x0e, 0x6e, 0xf6, 0xea, 0x45, + 0x0b, 0xb5, 0x45, 0x0b, 0x79, 0x6d, 0xe4, 0x89, 0x4e, 0xdd, 0xba, 0xde, 0x40, 0x62, 0xff, 0x86, + 0xd8, 0x46, 0x76, 0xaf, 0x05, 0x3d, 0xf2, 0x4b, 0xf3, 0xd6, 0xee, 0x75, 0x32, 0x12, 0xc5, 0xb6, + 0xd3, 0xe8, 0x9a, 0xfe, 0x4c, 0xf0, 0xc4, 0xfe, 0xbb, 0xf5, 0xd5, 0x60, 0x92, 0xbd, 0xfd, 0x57, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x16, 0x48, 0x29, 0x7a, 0x0d, 0x00, 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/02-client/migrations/v7/store.go b/modules/core/02-client/migrations/v7/store.go new file mode 100644 index 00000000000..2be30467000 --- /dev/null +++ b/modules/core/02-client/migrations/v7/store.go @@ -0,0 +1,215 @@ +package v7 + +import ( + "fmt" + "strings" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v6/modules/core/24-host" + "github.com/cosmos/ibc-go/v6/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v6/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint" +) + +// Localhost is the client type for a localhost client. It is also used as the clientID +// for the localhost client. +const Localhost string = "09-localhost" + +// MigrateStore performs in-place store migrations from ibc-go v6 to ibc-go v7. +// The migration includes: +// +// - Migrating solo machine client states from v2 to v3 protobuf definition +// - Pruning all solo machine consensus states +// - Removing the localhost client +// - Asserting existing tendermint clients are properly registered on the chain codec +func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { + store := ctx.KVStore(storeKey) + + if err := handleSolomachineMigration(ctx, store, cdc); err != nil { + return err + } + + if err := handleTendermintMigration(ctx, store, cdc); err != nil { + return err + } + + if err := handleLocalhostMigration(ctx, store, cdc); err != nil { + return err + } + + return nil +} + +// handleSolomachineMigration iterates over the solo machine clients and migrates client state from +// protobuf definition v2 to v3. All consensus states stored outside of the client state are pruned. +func handleSolomachineMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec) error { + clients, err := collectClients(ctx, store, exported.Solomachine) + if err != nil { + return err + } + + for _, clientID := range clients { + clientPrefix := []byte(fmt.Sprintf("%s/%s/", host.KeyClientStorePrefix, clientID)) + clientStore := prefix.NewStore(store, clientPrefix) + + bz := clientStore.Get(host.ClientStateKey()) + if bz == nil { + return sdkerrors.Wrapf(clienttypes.ErrClientNotFound, "clientID %s", clientID) + } + + var any codectypes.Any + if err := cdc.Unmarshal(bz, &any); err != nil { + return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") + } + + var clientState ClientState + if err := cdc.Unmarshal(any.Value, &clientState); err != nil { + return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") + } + + updatedClientState := migrateSolomachine(clientState) + + bz, err := clienttypes.MarshalClientState(cdc, &updatedClientState) + if err != nil { + return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") + } + + // update solomachine in store + clientStore.Set(host.ClientStateKey(), bz) + + removeAllClientConsensusStates(clientStore) + } + + return nil +} + +// handlerTendermintMigration asserts that the tendermint client in state can be decoded properly. +// This ensures the upgrading chain properly registered the tendermint client types on the chain codec. +func handleTendermintMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec) error { + clients, err := collectClients(ctx, store, exported.Tendermint) + if err != nil { + return err + } + + if len(clients) > 1 { + return sdkerrors.Wrap(sdkerrors.ErrLogic, "more than one Tendermint client collected") + } + + clientID := clients[0] + + clientPrefix := []byte(fmt.Sprintf("%s/%s/", host.KeyClientStorePrefix, clientID)) + clientStore := prefix.NewStore(store, clientPrefix) + + bz := clientStore.Get(host.ClientStateKey()) + if bz == nil { + return clienttypes.ErrClientNotFound + } + + var clientState exported.ClientState + if err := cdc.UnmarshalInterface(bz, &clientState); err != nil { + return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into tendermint client state") + } + + _, ok := clientState.(*ibctm.ClientState) + if !ok { + return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "client state is not tendermint even though client id contains 07-tendermint") + } + + return nil +} + +// handleLocalhostMigration removes all client and consensus states associated with the localhost client type. +func handleLocalhostMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec) error { + clients, err := collectClients(ctx, store, Localhost) + if err != nil { + return err + } + + for _, clientID := range clients { + clientPrefix := []byte(fmt.Sprintf("%s/%s/", host.KeyClientStorePrefix, clientID)) + clientStore := prefix.NewStore(store, clientPrefix) + + // delete the client state + clientStore.Delete(host.ClientStateKey()) + + removeAllClientConsensusStates(clientStore) + } + + return nil +} + +// collectClients will iterate over the provided client type prefix in the client store +// and return a list of clientIDs associated with the client type. This is necessary to +// avoid state corruption as modifying state during iteration is unsafe. A special case +// for tendermint clients is included as only one tendermint clientID is required for +// v7 migrations. +func collectClients(ctx sdk.Context, store sdk.KVStore, clientType string) (clients []string, err error) { + clientPrefix := []byte(fmt.Sprintf("%s/%s", host.KeyClientStorePrefix, clientType)) + iterator := sdk.KVStorePrefixIterator(store, clientPrefix) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + path := string(iterator.Key()) + if !strings.Contains(path, host.KeyClientState) { + // skip non client state keys + continue + } + + clientID := host.MustParseClientStatePath(path) + clients = append(clients, clientID) + + // optimization: exit after a single tendermint client iteration + if strings.Contains(clientID, exported.Tendermint) { + return clients, nil + } + } + + return clients, nil +} + +// removeAllClientConsensusStates removes all client consensus states from the associated +// client store. +func removeAllClientConsensusStates(clientStore sdk.KVStore) { + iterator := sdk.KVStorePrefixIterator(clientStore, []byte(host.KeyConsensusStatePrefix)) + var heights []exported.Height + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + keySplit := strings.Split(string(iterator.Key()), "/") + // key is in the format "consensusStates/" + if len(keySplit) != 2 || keySplit[0] != string(host.KeyConsensusStatePrefix) { + continue + } + + // collect consensus states to be pruned + heights = append(heights, clienttypes.MustParseHeight(keySplit[1])) + } + + // delete all consensus states + for _, height := range heights { + clientStore.Delete(host.ConsensusStateKey(height)) + } +} + +// migrateSolomachine migrates the solomachine from v2 to v3 solo machine protobuf definition. +// Notably it drops the AllowUpdateAfterProposal field. +func migrateSolomachine(clientState ClientState) solomachine.ClientState { + consensusState := &solomachine.ConsensusState{ + PublicKey: clientState.ConsensusState.PublicKey, + Diversifier: clientState.ConsensusState.Diversifier, + Timestamp: clientState.ConsensusState.Timestamp, + } + + return solomachine.ClientState{ + Sequence: clientState.Sequence, + IsFrozen: clientState.IsFrozen, + ConsensusState: consensusState, + } +} diff --git a/modules/core/02-client/migrations/v7/store_test.go b/modules/core/02-client/migrations/v7/store_test.go new file mode 100644 index 00000000000..c67425ea8bd --- /dev/null +++ b/modules/core/02-client/migrations/v7/store_test.go @@ -0,0 +1,169 @@ +package v7_test + +import ( + "strconv" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/v6/modules/core/02-client/migrations/v7" + "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v6/modules/core/24-host" + solomachine "github.com/cosmos/ibc-go/v6/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v6/testing" +) + +// numCreations is the number of clients/consensus states created for +// solo machine and localhost clients +const numCreations = 10 + +type MigrationsV7TestSuite struct { + suite.Suite + + coordinator *ibctesting.Coordinator + + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain +} + +func (suite *MigrationsV7TestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) +} + +func TestIBCTestSuite(t *testing.T) { + suite.Run(t, new(MigrationsV7TestSuite)) +} + +// test that MigrateStore returns an error if the codec used doesn't register tendermint types +func (suite *MigrationsV7TestSuite) TestMigrateStoreTendermint() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(path) + + registry := codectypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(registry) + + solomachine.RegisterInterfaces(registry) + err := v7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(host.StoreKey), cdc) + suite.Require().Error(err) + + ibctm.RegisterInterfaces(registry) + err = v7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(host.StoreKey), cdc) + suite.Require().NoError(err) +} + +// create multiple solo machine clients, tendermint and localhost clients +// ensure that solo machine clients are migrated and their consensus states are removed +// ensure the localhost is deleted entirely. +func (suite *MigrationsV7TestSuite) TestMigrateStore() { + paths := []*ibctesting.Path{ + ibctesting.NewPath(suite.chainA, suite.chainB), + ibctesting.NewPath(suite.chainA, suite.chainB), + } + + // create tendermint clients + for _, path := range paths { + suite.coordinator.SetupClients(path) + } + + solomachines := []*ibctesting.Solomachine{ + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1), + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4), + } + + suite.createSolomachineClients(solomachines) + suite.createLocalhostClients() + + err := v7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(host.StoreKey), suite.chainA.App.AppCodec()) + suite.Require().NoError(err) + + suite.assertSolomachineClients(solomachines) + suite.assertNoLocalhostClients() +} + +func (suite *MigrationsV7TestSuite) createSolomachineClients(solomachines []*ibctesting.Solomachine) { + // manually generate old protobuf definitions and set in store + // NOTE: we cannot use 'CreateClient' and 'UpdateClient' functions since we are + // using client states and consensus states which do not implement the exported.ClientState + // and exported.ConsensusState interface + for _, sm := range solomachines { + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), sm.ClientID) + clientState := sm.ClientState() + + // generate old client state proto definition + legacyClientState := &v7.ClientState{ + Sequence: clientState.Sequence, + ConsensusState: &v7.ConsensusState{ + PublicKey: clientState.ConsensusState.PublicKey, + Diversifier: clientState.ConsensusState.Diversifier, + Timestamp: clientState.ConsensusState.Timestamp, + }, + AllowUpdateAfterProposal: true, + } + + // set client state + bz, err := suite.chainA.App.AppCodec().MarshalInterface(legacyClientState) + suite.Require().NoError(err) + clientStore.Set(host.ClientStateKey(), bz) + + bz, err = suite.chainA.App.AppCodec().MarshalInterface(legacyClientState.ConsensusState) + suite.Require().NoError(err) + + // set some consensus states + for i := uint64(0); i < numCreations; i++ { + height := types.NewHeight(1, i) + clientStore.Set(host.ConsensusStateKey(height), bz) + } + + } +} + +func (suite *MigrationsV7TestSuite) assertSolomachineClients(solomachines []*ibctesting.Solomachine) { + // verify client state has been migrated + for _, sm := range solomachines { + clientState, ok := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), sm.ClientID) + suite.Require().True(ok) + suite.Require().Equal(sm.ClientState(), clientState) + + for i := uint64(0); i < numCreations; i++ { + height := types.NewHeight(1, i) + + consState, ok := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), sm.ClientID, height) + suite.Require().False(ok) + suite.Require().Empty(consState) + } + } +} + +// createLocalhostClients clients creates multiple localhost clients and multiple consensus states for each +func (suite *MigrationsV7TestSuite) createLocalhostClients() { + for numClients := uint64(0); numClients < numCreations; numClients++ { + clientID := v7.Localhost + "-" + strconv.FormatUint(numClients, 10) + clientStore := suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID) + + clientStore.Set(host.ClientStateKey(), []byte("clientState")) + + for i := 0; i < numCreations; i++ { + clientStore.Set(host.ConsensusStateKey(types.NewHeight(1, uint64(i))), []byte("consensusState")) + } + } +} + +// assertLocalhostClients asserts that all localhost information has been deleted +func (suite *MigrationsV7TestSuite) assertNoLocalhostClients() { + for numClients := uint64(0); numClients < numCreations; numClients++ { + clientID := v7.Localhost + "-" + strconv.FormatUint(numClients, 10) + clientStore := suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID) + + suite.Require().False(clientStore.Has(host.ClientStateKey())) + + for i := uint64(0); i < numCreations; i++ { + suite.Require().False(clientStore.Has(host.ConsensusStateKey(types.NewHeight(1, i)))) + } + } +} diff --git a/modules/core/keeper/migrations.go b/modules/core/keeper/migrations.go index 2984ad9c016..0885dbb7ad9 100644 --- a/modules/core/keeper/migrations.go +++ b/modules/core/keeper/migrations.go @@ -30,3 +30,13 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { return nil } + +// Migrate2to3 migrates from version 2 to 3. See 02-client keeper function Migrate2to3. +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + clientMigrator := clientkeeper.NewMigrator(m.keeper.ClientKeeper) + if err := clientMigrator.Migrate2to3(ctx); err != nil { + return err + } + + return nil +} diff --git a/modules/core/module.go b/modules/core/module.go index dc46d4718b1..02cc5e2b3fc 100644 --- a/modules/core/module.go +++ b/modules/core/module.go @@ -144,6 +144,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err != nil { panic(err) } + err = cfg.RegisterMigration(host.ModuleName, 2, m.Migrate2to3) + if err != nil { + panic(err) + } } // InitGenesis performs genesis initialization for the ibc module. It returns @@ -165,7 +169,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 2 } +func (AppModule) ConsensusVersion() uint64 { return 3 } // BeginBlock returns the begin blocker for the ibc module. func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { diff --git a/proto/ibc/lightclients/solomachine/v2/solomachine.proto b/proto/ibc/lightclients/solomachine/v2/solomachine.proto index faf71334711..6964404dd14 100644 --- a/proto/ibc/lightclients/solomachine/v2/solomachine.proto +++ b/proto/ibc/lightclients/solomachine/v2/solomachine.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.lightclients.solomachine.v2; -option go_package = "github.com/cosmos/ibc-go/v6/modules/core/02-client/migrations/v6"; +option go_package = "github.com/cosmos/ibc-go/v6/modules/core/02-client/migrations/v7"; import "ibc/core/connection/v1/connection.proto"; import "ibc/core/channel/v1/channel.proto";