From 34409d75dff4ef8c5a4d499779283b8385b7ff19 Mon Sep 17 00:00:00 2001 From: mpoke Date: Mon, 4 Nov 2024 16:08:21 +0100 Subject: [PATCH 01/25] add connection_id to init params --- .../ccv/provider/v1/provider.proto | 10 +- x/ccv/provider/types/provider.pb.go | 349 ++++++++++-------- 2 files changed, 211 insertions(+), 148 deletions(-) diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index 138e5fa23b..f77c5eb74d 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -94,7 +94,7 @@ message ConsumerAdditionProposal { // sub-protocol. If DistributionTransmissionChannel == "", a new transfer // channel is created on top of the same connection as the CCV channel. // Note that transfer_channel_id is the ID of the channel end on the consumer - // chain. it is most relevant for chains performing a sovereign to consumer + // chain. It is most relevant for chains performing a standalone to consumer // changeover in order to maintain the existing ibc transfer channel string distribution_transmission_channel = 14; // Corresponds to the percentage of validators that have to validate the chain under the Top N case. @@ -466,9 +466,15 @@ message ConsumerInitializationParameters { // sub-protocol. If DistributionTransmissionChannel == "", a new transfer // channel is created on top of the same connection as the CCV channel. // Note that transfer_channel_id is the ID of the channel end on the consumer - // chain. it is most relevant for chains performing a sovereign to consumer + // chain. It is most relevant for chains performing a standalone to consumer // changeover in order to maintain the existing ibc transfer channel string distribution_transmission_channel = 11; + // The ID of the connection end on the provider chain on top of which the CCV + // channel will be established. If connection_id == "", a new client of the + // consumer chain and a new connection on top of this client are created. + // Note that a standalone chain can transition to a consumer chain while + // maintaining existing IBC channels to other chains by providing a valid connection_id. + string connection_id = 12; } // PowerShapingParameters contains parameters that shape the validator set that we send to the consumer chain diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index ae7402200e..29b3b118f7 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -141,7 +141,7 @@ type ConsumerAdditionProposal struct { // sub-protocol. If DistributionTransmissionChannel == "", a new transfer // channel is created on top of the same connection as the CCV channel. // Note that transfer_channel_id is the ID of the channel end on the consumer - // chain. it is most relevant for chains performing a sovereign to consumer + // chain. It is most relevant for chains performing a standalone to consumer // changeover in order to maintain the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,14,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` // Corresponds to the percentage of validators that have to validate the chain under the Top N case. @@ -1537,9 +1537,15 @@ type ConsumerInitializationParameters struct { // sub-protocol. If DistributionTransmissionChannel == "", a new transfer // channel is created on top of the same connection as the CCV channel. // Note that transfer_channel_id is the ID of the channel end on the consumer - // chain. it is most relevant for chains performing a sovereign to consumer + // chain. It is most relevant for chains performing a standalone to consumer // changeover in order to maintain the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,11,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // The ID of the connection end on the provider chain on top of which the CCV + // channel will be established. If connection_id == "", a new client of the + // consumer chain and a new connection on top of this client are created. + // Note that a standalone chain can transition to a consumer chain while + // maintaining existing IBC channels to other chains by providing a valid connection_id. + ConnectionId string `protobuf:"bytes,12,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` } func (m *ConsumerInitializationParameters) Reset() { *m = ConsumerInitializationParameters{} } @@ -1652,6 +1658,13 @@ func (m *ConsumerInitializationParameters) GetDistributionTransmissionChannel() return "" } +func (m *ConsumerInitializationParameters) GetConnectionId() string { + if m != nil { + return m.ConnectionId + } + return "" +} + // PowerShapingParameters contains parameters that shape the validator set that we send to the consumer chain type PowerShapingParameters struct { // Corresponds to the percentage of validators that have to validate the chain under the Top N case. @@ -1919,150 +1932,151 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 2280 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x6f, 0x1b, 0xc7, - 0xd9, 0xd7, 0x8a, 0x94, 0x44, 0x0e, 0xf5, 0x41, 0x8d, 0x1d, 0x99, 0x92, 0x15, 0x92, 0xde, 0xbc, - 0x0e, 0xf8, 0xda, 0x35, 0x19, 0x29, 0x40, 0x61, 0xb8, 0x0d, 0x0c, 0x9a, 0xa4, 0x6d, 0xfa, 0x43, - 0x66, 0x97, 0xb4, 0x02, 0xb8, 0x87, 0xc5, 0x70, 0x77, 0x44, 0x4e, 0xb5, 0xbb, 0xb3, 0xde, 0x19, - 0xae, 0xcd, 0x1e, 0x7a, 0x0e, 0x0a, 0x14, 0x48, 0x6f, 0x41, 0x2f, 0x0d, 0xd0, 0x4b, 0xd1, 0x53, - 0x0f, 0x45, 0xfe, 0x80, 0x9e, 0xd2, 0x02, 0x05, 0xd2, 0x5b, 0x4f, 0x49, 0x61, 0x1f, 0x7a, 0x28, - 0xd0, 0x9e, 0x7b, 0x2b, 0x66, 0xf6, 0x83, 0x4b, 0x7d, 0x99, 0x86, 0xed, 0x5e, 0xa4, 0x9d, 0x79, - 0x7e, 0xcf, 0x33, 0xcf, 0x33, 0xf3, 0x7c, 0xcd, 0x10, 0xec, 0x12, 0x87, 0x63, 0xcf, 0x18, 0x22, - 0xe2, 0xe8, 0x0c, 0x1b, 0x23, 0x8f, 0xf0, 0x71, 0xcd, 0x30, 0xfc, 0x9a, 0xeb, 0x51, 0x9f, 0x98, - 0xd8, 0xab, 0xf9, 0x3b, 0xf1, 0x77, 0xd5, 0xf5, 0x28, 0xa7, 0xf0, 0x83, 0x13, 0x78, 0xaa, 0x86, - 0xe1, 0x57, 0x63, 0x9c, 0xbf, 0xb3, 0xb5, 0x8e, 0x6c, 0xe2, 0xd0, 0x9a, 0xfc, 0x1b, 0xf0, 0x6d, - 0x15, 0x0d, 0xca, 0x6c, 0xca, 0x6a, 0x7d, 0xc4, 0x70, 0xcd, 0xdf, 0xe9, 0x63, 0x8e, 0x76, 0x6a, - 0x06, 0x25, 0x4e, 0x48, 0xff, 0x30, 0xa4, 0x63, 0x21, 0xc4, 0x31, 0x26, 0x98, 0x68, 0x22, 0xc4, - 0x6d, 0x06, 0x38, 0x5d, 0x8e, 0x6a, 0xc1, 0x20, 0x24, 0x9d, 0x1f, 0xd0, 0x01, 0x0d, 0xe6, 0xc5, - 0x57, 0xb4, 0xf0, 0x80, 0xd2, 0x81, 0x85, 0x6b, 0x72, 0xd4, 0x1f, 0x1d, 0xd4, 0xcc, 0x91, 0x87, - 0x38, 0xa1, 0xd1, 0xc2, 0xa5, 0xa3, 0x74, 0x4e, 0x6c, 0xcc, 0x38, 0xb2, 0xdd, 0x08, 0x40, 0xfa, - 0x46, 0xcd, 0xa0, 0x1e, 0xae, 0x19, 0x16, 0xc1, 0x0e, 0x17, 0x9b, 0x12, 0x7c, 0x85, 0x80, 0x9a, - 0x00, 0x58, 0x64, 0x30, 0xe4, 0xc1, 0x34, 0xab, 0x71, 0xec, 0x98, 0xd8, 0xb3, 0x49, 0x00, 0x9e, - 0x8c, 0x42, 0x86, 0xcb, 0xa7, 0xed, 0xbb, 0xbf, 0x53, 0x7b, 0x46, 0xbc, 0xc8, 0xd4, 0xed, 0x84, - 0x18, 0xc3, 0x1b, 0xbb, 0x9c, 0xd6, 0x0e, 0xf1, 0x38, 0xb4, 0x56, 0xfd, 0x4f, 0x06, 0x14, 0x1a, - 0xd4, 0x61, 0x23, 0x1b, 0x7b, 0x75, 0xd3, 0x24, 0xc2, 0xa4, 0x8e, 0x47, 0x5d, 0xca, 0x90, 0x05, - 0xcf, 0x83, 0x05, 0x4e, 0xb8, 0x85, 0x0b, 0x4a, 0x59, 0xa9, 0x64, 0xb5, 0x60, 0x00, 0xcb, 0x20, - 0x67, 0x62, 0x66, 0x78, 0xc4, 0x15, 0xe0, 0xc2, 0xbc, 0xa4, 0x25, 0xa7, 0xe0, 0x26, 0xc8, 0x04, - 0x6a, 0x11, 0xb3, 0x90, 0x92, 0xe4, 0x25, 0x39, 0x6e, 0x9b, 0xf0, 0x0e, 0x58, 0x25, 0x0e, 0xe1, - 0x04, 0x59, 0xfa, 0x10, 0x0b, 0x63, 0x0b, 0xe9, 0xb2, 0x52, 0xc9, 0xed, 0x6e, 0x55, 0x49, 0xdf, - 0xa8, 0x8a, 0xfd, 0xa9, 0x86, 0xbb, 0xe2, 0xef, 0x54, 0xef, 0x4a, 0xc4, 0xad, 0xf4, 0xd7, 0xdf, - 0x96, 0xe6, 0xb4, 0x95, 0x90, 0x2f, 0x98, 0x84, 0x97, 0xc0, 0xf2, 0x00, 0x3b, 0x98, 0x11, 0xa6, - 0x0f, 0x11, 0x1b, 0x16, 0x16, 0xca, 0x4a, 0x65, 0x59, 0xcb, 0x85, 0x73, 0x77, 0x11, 0x1b, 0xc2, - 0x12, 0xc8, 0xf5, 0x89, 0x83, 0xbc, 0x71, 0x80, 0x58, 0x94, 0x08, 0x10, 0x4c, 0x49, 0x40, 0x03, - 0x00, 0xe6, 0xa2, 0x67, 0x8e, 0x2e, 0x0e, 0xab, 0xb0, 0x14, 0x2a, 0x12, 0x9c, 0x64, 0x35, 0x3a, - 0xc9, 0x6a, 0x2f, 0x3a, 0xc9, 0x5b, 0x19, 0xa1, 0xc8, 0xe7, 0xdf, 0x95, 0x14, 0x2d, 0x2b, 0xf9, - 0x04, 0x05, 0xee, 0x81, 0xfc, 0xc8, 0xe9, 0x53, 0xc7, 0x24, 0xce, 0x40, 0x77, 0xb1, 0x47, 0xa8, - 0x59, 0xc8, 0x48, 0x51, 0x9b, 0xc7, 0x44, 0x35, 0x43, 0xa7, 0x09, 0x24, 0x7d, 0x21, 0x24, 0xad, - 0xc5, 0xcc, 0x1d, 0xc9, 0x0b, 0x7f, 0x04, 0xa0, 0x61, 0xf8, 0x52, 0x25, 0x3a, 0xe2, 0x91, 0xc4, - 0xec, 0xec, 0x12, 0xf3, 0x86, 0xe1, 0xf7, 0x02, 0xee, 0x50, 0xe4, 0x8f, 0xc1, 0x05, 0xee, 0x21, - 0x87, 0x1d, 0x60, 0xef, 0xa8, 0x5c, 0x30, 0xbb, 0xdc, 0xf7, 0x22, 0x19, 0xd3, 0xc2, 0xef, 0x82, - 0xb2, 0x11, 0x3a, 0x90, 0xee, 0x61, 0x93, 0x30, 0xee, 0x91, 0xfe, 0x48, 0xf0, 0xea, 0x07, 0x1e, - 0x32, 0xa4, 0x8f, 0xe4, 0xa4, 0x13, 0x14, 0x23, 0x9c, 0x36, 0x05, 0xbb, 0x1d, 0xa2, 0xe0, 0x23, - 0xf0, 0x7f, 0x7d, 0x8b, 0x1a, 0x87, 0x4c, 0x28, 0xa7, 0x4f, 0x49, 0x92, 0x4b, 0xdb, 0x84, 0x31, - 0x21, 0x6d, 0xb9, 0xac, 0x54, 0x52, 0xda, 0xa5, 0x00, 0xdb, 0xc1, 0x5e, 0x33, 0x81, 0xec, 0x25, - 0x80, 0xf0, 0x1a, 0x80, 0x43, 0xc2, 0x38, 0xf5, 0x88, 0x81, 0x2c, 0x1d, 0x3b, 0xdc, 0x23, 0x98, - 0x15, 0x56, 0x24, 0xfb, 0xfa, 0x84, 0xd2, 0x0a, 0x08, 0xf0, 0x1e, 0xb8, 0x74, 0xea, 0xa2, 0xba, - 0x31, 0x44, 0x8e, 0x83, 0xad, 0xc2, 0xaa, 0x34, 0xa5, 0x64, 0x9e, 0xb2, 0x66, 0x23, 0x80, 0xc1, - 0x73, 0x60, 0x81, 0x53, 0x57, 0xdf, 0x2b, 0xac, 0x95, 0x95, 0xca, 0x8a, 0x96, 0xe6, 0xd4, 0xdd, - 0x83, 0x1f, 0x81, 0xf3, 0x3e, 0xb2, 0x88, 0x89, 0x38, 0xf5, 0x98, 0xee, 0xd2, 0x67, 0xd8, 0xd3, - 0x0d, 0xe4, 0x16, 0xf2, 0x12, 0x03, 0x27, 0xb4, 0x8e, 0x20, 0x35, 0x90, 0x0b, 0xaf, 0x80, 0xf5, - 0x78, 0x56, 0x67, 0x98, 0x4b, 0xf8, 0xba, 0x84, 0xaf, 0xc5, 0x84, 0x2e, 0xe6, 0x02, 0xbb, 0x0d, - 0xb2, 0xc8, 0xb2, 0xe8, 0x33, 0x8b, 0x30, 0x5e, 0x80, 0xe5, 0x54, 0x25, 0xab, 0x4d, 0x26, 0xe0, - 0x16, 0xc8, 0x98, 0xd8, 0x19, 0x4b, 0xe2, 0x39, 0x49, 0x8c, 0xc7, 0xf0, 0x22, 0xc8, 0xda, 0x22, - 0x89, 0x70, 0x74, 0x88, 0x0b, 0xe7, 0xcb, 0x4a, 0x25, 0xad, 0x65, 0x6c, 0xe2, 0x74, 0xc5, 0x18, - 0x56, 0xc1, 0x39, 0x29, 0x45, 0x27, 0x8e, 0x38, 0x27, 0x1f, 0xeb, 0x3e, 0xb2, 0x58, 0xe1, 0xbd, - 0xb2, 0x52, 0xc9, 0x68, 0xeb, 0x92, 0xd4, 0x0e, 0x29, 0xfb, 0xc8, 0x62, 0x37, 0x2a, 0x9f, 0x7d, - 0x59, 0x9a, 0xfb, 0xe2, 0xcb, 0xd2, 0xdc, 0x9f, 0xff, 0x70, 0x6d, 0x2b, 0xcc, 0xac, 0x03, 0xea, - 0x57, 0xc3, 0x4c, 0x5c, 0x6d, 0x50, 0x87, 0x63, 0x87, 0x17, 0x14, 0xf5, 0xaf, 0x0a, 0xb8, 0xd0, - 0x88, 0x5d, 0xc2, 0xa6, 0x3e, 0xb2, 0xde, 0x65, 0xea, 0xa9, 0x83, 0x2c, 0x13, 0x67, 0x22, 0x83, - 0x3d, 0xfd, 0x1a, 0xc1, 0x9e, 0x11, 0x6c, 0x82, 0x70, 0xa3, 0xfc, 0x4a, 0x9b, 0xfe, 0x3d, 0x0f, - 0xb6, 0x23, 0x9b, 0x1e, 0x52, 0x93, 0x1c, 0x10, 0x03, 0xbd, 0xeb, 0x9c, 0x1a, 0xfb, 0x5a, 0x7a, - 0x06, 0x5f, 0x5b, 0x78, 0x3d, 0x5f, 0x5b, 0x9c, 0xc1, 0xd7, 0x96, 0xce, 0xf2, 0xb5, 0xcc, 0x59, - 0xbe, 0x96, 0x9d, 0xcd, 0xd7, 0xc0, 0x69, 0xbe, 0x36, 0x5f, 0x50, 0xd4, 0x5f, 0x2b, 0xe0, 0x7c, - 0xeb, 0xe9, 0x88, 0xf8, 0xf4, 0x2d, 0xed, 0xf4, 0x7d, 0xb0, 0x82, 0x13, 0xf2, 0x58, 0x21, 0x55, - 0x4e, 0x55, 0x72, 0xbb, 0x97, 0xab, 0xe1, 0xc1, 0xc7, 0xad, 0x44, 0x74, 0xfa, 0xc9, 0xd5, 0xb5, - 0x69, 0x5e, 0xa9, 0xe1, 0x1f, 0x15, 0xb0, 0x25, 0xf2, 0xc2, 0x00, 0x6b, 0xf8, 0x19, 0xf2, 0xcc, - 0x26, 0x76, 0xa8, 0xcd, 0xde, 0x58, 0x4f, 0x15, 0xac, 0x98, 0x52, 0x92, 0xce, 0xa9, 0x8e, 0x4c, - 0x53, 0xea, 0x29, 0x31, 0x62, 0xb2, 0x47, 0xeb, 0xa6, 0x09, 0x2b, 0x20, 0x3f, 0xc1, 0x78, 0x22, - 0xc6, 0x84, 0xeb, 0x0b, 0xd8, 0x6a, 0x04, 0x93, 0x91, 0x87, 0x6f, 0x14, 0xcf, 0x76, 0x6d, 0xf5, - 0x9f, 0x0a, 0xc8, 0xdf, 0xb1, 0x68, 0x1f, 0x59, 0x5d, 0x0b, 0xb1, 0xa1, 0xc8, 0x99, 0x63, 0x11, - 0x52, 0x1e, 0x0e, 0x8b, 0x95, 0x54, 0x7f, 0xe6, 0x90, 0x12, 0x6c, 0xb2, 0x7c, 0xde, 0x04, 0xeb, - 0x71, 0xf9, 0x88, 0x1d, 0x5c, 0x5a, 0x7b, 0xeb, 0xdc, 0x8b, 0x6f, 0x4b, 0x6b, 0x51, 0x30, 0x35, - 0xa4, 0xb3, 0x37, 0xb5, 0x35, 0x63, 0x6a, 0xc2, 0x84, 0x45, 0x90, 0x23, 0x7d, 0x43, 0x67, 0xf8, - 0xa9, 0xee, 0x8c, 0x6c, 0x19, 0x1b, 0x69, 0x2d, 0x4b, 0xfa, 0x46, 0x17, 0x3f, 0xdd, 0x1b, 0xd9, - 0xf0, 0x63, 0xb0, 0x11, 0x35, 0x95, 0xc2, 0x9b, 0x74, 0xc1, 0x2f, 0xb6, 0xcb, 0x93, 0xe1, 0xb2, - 0xac, 0x9d, 0x8b, 0xa8, 0xfb, 0xc8, 0x12, 0x8b, 0xd5, 0x4d, 0xd3, 0x53, 0xff, 0xb5, 0x00, 0x16, - 0x3b, 0xc8, 0x43, 0x36, 0x83, 0x3d, 0xb0, 0xc6, 0xb1, 0xed, 0x5a, 0x88, 0x63, 0x3d, 0x68, 0x4d, - 0x42, 0x4b, 0xaf, 0xca, 0x96, 0x25, 0xd9, 0xb1, 0x55, 0x13, 0x3d, 0x9a, 0xbf, 0x53, 0x6d, 0xc8, - 0xd9, 0x2e, 0x47, 0x1c, 0x6b, 0xab, 0x91, 0x8c, 0x60, 0x12, 0x5e, 0x07, 0x05, 0xee, 0x8d, 0x18, - 0x9f, 0x34, 0x0d, 0x93, 0x6a, 0x19, 0x9c, 0xf5, 0x46, 0x44, 0x0f, 0xea, 0x6c, 0x5c, 0x25, 0x4f, - 0xee, 0x0f, 0x52, 0x6f, 0xd2, 0x1f, 0x98, 0x60, 0x9b, 0x89, 0x43, 0xd5, 0x6d, 0xcc, 0x65, 0x15, - 0x77, 0x2d, 0xec, 0x10, 0x36, 0x8c, 0x84, 0x2f, 0xce, 0x2e, 0x7c, 0x53, 0x0a, 0x7a, 0x28, 0xe4, - 0x68, 0x91, 0x98, 0x70, 0x95, 0x06, 0x28, 0x9e, 0xbc, 0x4a, 0x6c, 0xf8, 0x92, 0x34, 0xfc, 0xe2, - 0x09, 0x22, 0x62, 0xeb, 0x19, 0xf8, 0x30, 0xd1, 0x6d, 0x88, 0x68, 0xd2, 0xa5, 0x23, 0xeb, 0x1e, - 0x1e, 0x88, 0x92, 0x8c, 0x82, 0xc6, 0x03, 0xe3, 0xb8, 0x63, 0x0a, 0x7d, 0x5a, 0xdc, 0x18, 0x12, - 0x4e, 0x4d, 0x9c, 0xb0, 0xad, 0x54, 0x27, 0x4d, 0x49, 0x1c, 0x9b, 0x5a, 0x42, 0xd6, 0x6d, 0x8c, - 0x45, 0x14, 0x25, 0x1a, 0x13, 0xec, 0x52, 0x63, 0x28, 0x73, 0x52, 0x4a, 0x5b, 0x8d, 0x9b, 0x90, - 0x96, 0x98, 0x85, 0x4f, 0xc0, 0x55, 0x67, 0x64, 0xf7, 0xb1, 0xa7, 0xd3, 0x83, 0x00, 0x28, 0x23, - 0x8f, 0x71, 0xe4, 0x71, 0xdd, 0xc3, 0x06, 0x26, 0xbe, 0x38, 0xf1, 0x40, 0x73, 0x26, 0xfb, 0xa2, - 0x94, 0x76, 0x39, 0x60, 0x79, 0x74, 0x20, 0x65, 0xb0, 0x1e, 0xed, 0x0a, 0xb8, 0x16, 0xa1, 0x03, - 0xc5, 0x18, 0x6c, 0x83, 0x4b, 0x36, 0x7a, 0xae, 0xc7, 0xce, 0x2c, 0x14, 0xc7, 0x0e, 0x1b, 0x31, - 0x7d, 0x92, 0xcc, 0xc3, 0xde, 0xa8, 0x68, 0xa3, 0xe7, 0x9d, 0x10, 0xd7, 0x88, 0x60, 0xfb, 0x31, - 0xea, 0x5e, 0x3a, 0x93, 0xce, 0x2f, 0xdc, 0x4b, 0x67, 0x16, 0xf2, 0x8b, 0xf7, 0xd2, 0x99, 0x4c, - 0x3e, 0xab, 0xfe, 0x3f, 0xc8, 0xca, 0xb8, 0xae, 0x1b, 0x87, 0x4c, 0x66, 0x77, 0xd3, 0xf4, 0x30, - 0x63, 0x98, 0x15, 0x94, 0x30, 0xbb, 0x47, 0x13, 0x2a, 0x07, 0x9b, 0xa7, 0xdd, 0x18, 0x18, 0xfc, - 0x14, 0x2c, 0xb9, 0x58, 0xb6, 0xb3, 0x92, 0x31, 0xb7, 0xfb, 0x49, 0x75, 0x86, 0xab, 0x5e, 0xf5, - 0x34, 0x81, 0x5a, 0x24, 0x4d, 0xf5, 0x26, 0xf7, 0x94, 0x23, 0xbd, 0x02, 0x83, 0xfb, 0x47, 0x17, - 0xfd, 0xe1, 0x6b, 0x2d, 0x7a, 0x44, 0xde, 0x64, 0xcd, 0xab, 0x20, 0x57, 0x0f, 0xcc, 0x7e, 0x20, - 0x4a, 0xd7, 0xb1, 0x6d, 0x59, 0x4e, 0x6e, 0xcb, 0x1e, 0x58, 0x0d, 0x9b, 0xbf, 0x1e, 0x95, 0xb9, - 0x09, 0xbe, 0x0f, 0x40, 0xd8, 0x35, 0x8a, 0x9c, 0x16, 0x64, 0xf7, 0x6c, 0x38, 0xd3, 0x36, 0xa7, - 0x2a, 0xfa, 0xfc, 0x54, 0x45, 0x97, 0x55, 0x83, 0x82, 0xcd, 0xfd, 0x64, 0xd5, 0x95, 0x05, 0xa4, - 0x83, 0x8c, 0x43, 0xcc, 0x19, 0xd4, 0x40, 0x5a, 0x56, 0xd7, 0xc0, 0xdc, 0xeb, 0xa7, 0x9a, 0xeb, - 0xef, 0x54, 0x4f, 0x13, 0xd2, 0x44, 0x1c, 0x85, 0x31, 0x20, 0x65, 0xa9, 0xbf, 0x54, 0x40, 0xe1, - 0x3e, 0x1e, 0xd7, 0x19, 0x23, 0x03, 0xc7, 0xc6, 0x0e, 0x17, 0xd1, 0x87, 0x0c, 0x2c, 0x3e, 0xe1, - 0x07, 0x60, 0x25, 0x76, 0x3c, 0x99, 0x3c, 0x15, 0x99, 0x3c, 0x97, 0xa3, 0x49, 0xb1, 0x4f, 0xf0, - 0x06, 0x00, 0xae, 0x87, 0x7d, 0xdd, 0xd0, 0x0f, 0xf1, 0x58, 0xda, 0x94, 0xdb, 0xdd, 0x4e, 0x26, - 0xc5, 0xe0, 0xfe, 0x59, 0xed, 0x8c, 0xfa, 0x16, 0x31, 0xee, 0xe3, 0xb1, 0x96, 0x11, 0xf8, 0xc6, - 0x7d, 0x3c, 0x16, 0x55, 0x50, 0x36, 0x29, 0x32, 0x93, 0xa5, 0xb4, 0x60, 0xa0, 0xfe, 0x4a, 0x01, - 0x17, 0x62, 0x03, 0xa2, 0xf3, 0xea, 0x8c, 0xfa, 0x82, 0x23, 0xb9, 0x7f, 0xca, 0x74, 0x47, 0x74, - 0x4c, 0xdb, 0xf9, 0x13, 0xb4, 0xbd, 0x09, 0x96, 0xe3, 0x54, 0x22, 0xf4, 0x4d, 0xcd, 0xa0, 0x6f, - 0x2e, 0xe2, 0xb8, 0x8f, 0xc7, 0xea, 0xcf, 0x12, 0xba, 0xdd, 0x1a, 0x27, 0x5c, 0xd8, 0x7b, 0x85, - 0x6e, 0xf1, 0xb2, 0x49, 0xdd, 0x8c, 0x24, 0xff, 0x31, 0x03, 0x52, 0xc7, 0x0d, 0x50, 0xff, 0xa2, - 0x80, 0x8d, 0xe4, 0xaa, 0xac, 0x47, 0x3b, 0xde, 0xc8, 0xc1, 0xfb, 0xbb, 0x67, 0xad, 0x7f, 0x13, - 0x64, 0x5c, 0x81, 0xd2, 0x39, 0x0b, 0x8f, 0x68, 0xb6, 0x92, 0xbd, 0x24, 0xb9, 0x7a, 0x22, 0xc4, - 0x57, 0xa7, 0x0c, 0x60, 0xe1, 0xce, 0x7d, 0x34, 0x53, 0xd0, 0x25, 0x02, 0x4a, 0x5b, 0x49, 0xda, - 0xcc, 0xd4, 0xaf, 0x14, 0x00, 0x8f, 0x67, 0x2b, 0xf8, 0x3d, 0x00, 0xa7, 0x72, 0x5e, 0xd2, 0xff, - 0xf2, 0x6e, 0x22, 0xcb, 0xc9, 0x9d, 0x8b, 0xfd, 0x68, 0x3e, 0xe1, 0x47, 0xf0, 0x07, 0x00, 0xb8, - 0xf2, 0x10, 0x67, 0x3e, 0xe9, 0xac, 0x1b, 0x7d, 0xc2, 0x12, 0xc8, 0xfd, 0x84, 0x12, 0x27, 0xf9, - 0x60, 0x91, 0xd2, 0x80, 0x98, 0x0a, 0xde, 0x22, 0xd4, 0x5f, 0x28, 0x93, 0x94, 0x18, 0x66, 0xeb, - 0xba, 0x65, 0x85, 0x3d, 0x20, 0x74, 0xc1, 0x52, 0x94, 0xef, 0x83, 0x70, 0xdd, 0x3e, 0xb1, 0x26, - 0x35, 0xb1, 0x21, 0xcb, 0xd2, 0x75, 0xb1, 0xe3, 0xbf, 0xfb, 0xae, 0x74, 0x75, 0x40, 0xf8, 0x70, - 0xd4, 0xaf, 0x1a, 0xd4, 0x0e, 0x1f, 0xa8, 0xc2, 0x7f, 0xd7, 0x98, 0x79, 0x58, 0xe3, 0x63, 0x17, - 0xb3, 0x88, 0x87, 0xfd, 0xf6, 0x1f, 0xbf, 0xbf, 0xa2, 0x68, 0xd1, 0x32, 0xaa, 0x09, 0xf2, 0xf1, - 0x1d, 0x04, 0x73, 0x64, 0x22, 0x8e, 0x20, 0x04, 0x69, 0x07, 0xd9, 0x51, 0x93, 0x29, 0xbf, 0x67, - 0xe8, 0x31, 0xb7, 0x40, 0xc6, 0x0e, 0x25, 0x84, 0xb7, 0x8e, 0x78, 0xac, 0xfe, 0x7c, 0x11, 0x94, - 0xa3, 0x65, 0xda, 0xc1, 0xdb, 0x0c, 0xf9, 0x69, 0xd0, 0x82, 0x8b, 0xce, 0x49, 0xd4, 0x6f, 0x76, - 0xc2, 0x7b, 0x8f, 0xf2, 0x76, 0xde, 0x7b, 0xe6, 0x5f, 0xf9, 0xde, 0x93, 0x7a, 0xc5, 0x7b, 0x4f, - 0xfa, 0xed, 0xbd, 0xf7, 0x2c, 0xbc, 0xf5, 0xf7, 0x9e, 0xc5, 0x77, 0xf4, 0xde, 0xb3, 0xf4, 0x3f, - 0x79, 0xef, 0xc9, 0xbc, 0xd5, 0xf7, 0x9e, 0xec, 0x9b, 0xbd, 0xf7, 0x80, 0x37, 0x7a, 0xef, 0xc9, - 0xcd, 0xf4, 0xde, 0xa3, 0x7e, 0x35, 0x0f, 0x36, 0xe4, 0x4d, 0xba, 0x3b, 0x44, 0xae, 0x38, 0xdc, - 0x49, 0x08, 0xc4, 0xd7, 0x73, 0x65, 0x86, 0xeb, 0xf9, 0xfc, 0xeb, 0x5d, 0xcf, 0x53, 0x33, 0x5c, - 0xcf, 0xd3, 0x67, 0x5d, 0xcf, 0x17, 0xce, 0xba, 0x9e, 0x2f, 0xce, 0x76, 0x3d, 0x5f, 0x3a, 0xe5, - 0x7a, 0x0e, 0x55, 0xb0, 0xec, 0x7a, 0x84, 0x8a, 0x3a, 0x90, 0x78, 0x0b, 0x98, 0x9a, 0x53, 0x4b, - 0x20, 0x17, 0x27, 0x11, 0x93, 0xc1, 0x3c, 0x48, 0x11, 0x33, 0x6a, 0x3a, 0xc5, 0xa7, 0xba, 0x03, - 0x2e, 0xd4, 0x23, 0xd5, 0xb1, 0x99, 0xbc, 0x41, 0xc3, 0x0d, 0xb0, 0x18, 0xdc, 0x62, 0x43, 0x7c, - 0x38, 0xba, 0xf2, 0x27, 0x05, 0xac, 0xc4, 0xcd, 0xc2, 0x10, 0x31, 0x0c, 0x8b, 0x60, 0xab, 0xf1, - 0x68, 0xaf, 0xfb, 0xf8, 0x61, 0x4b, 0xd3, 0x3b, 0x77, 0xeb, 0xdd, 0x96, 0xfe, 0x78, 0xaf, 0xdb, - 0x69, 0x35, 0xda, 0xb7, 0xdb, 0xad, 0x66, 0x7e, 0x0e, 0xbe, 0x0f, 0x36, 0x8f, 0xd0, 0xb5, 0xd6, - 0x9d, 0x76, 0xb7, 0xd7, 0xd2, 0x5a, 0xcd, 0xbc, 0x72, 0x02, 0x7b, 0x7b, 0xaf, 0xdd, 0x6b, 0xd7, - 0x1f, 0xb4, 0x9f, 0xb4, 0x9a, 0xf9, 0x79, 0x78, 0x11, 0x5c, 0x38, 0x42, 0x7f, 0x50, 0x7f, 0xbc, - 0xd7, 0xb8, 0xdb, 0x6a, 0xe6, 0x53, 0x70, 0x0b, 0x6c, 0x1c, 0x21, 0x76, 0x7b, 0x8f, 0x3a, 0x9d, - 0x56, 0x33, 0x9f, 0x3e, 0x81, 0xd6, 0x6c, 0x3d, 0x68, 0xf5, 0x5a, 0xcd, 0xfc, 0xc2, 0x56, 0xfa, - 0xb3, 0xdf, 0x14, 0xe7, 0x6e, 0x7d, 0xfa, 0xf5, 0x8b, 0xa2, 0xf2, 0xcd, 0x8b, 0xa2, 0xf2, 0xf7, - 0x17, 0x45, 0xe5, 0xf3, 0x97, 0xc5, 0xb9, 0x6f, 0x5e, 0x16, 0xe7, 0xfe, 0xf6, 0xb2, 0x38, 0xf7, - 0xe4, 0x93, 0xe3, 0x05, 0x62, 0x52, 0x80, 0xaf, 0xc5, 0xbf, 0x08, 0xf8, 0xdf, 0xaf, 0x3d, 0x9f, - 0xfe, 0x39, 0x46, 0xd6, 0x8e, 0xfe, 0xa2, 0x8c, 0xfd, 0x8f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, - 0x15, 0xc3, 0x5a, 0xbf, 0xbf, 0x19, 0x00, 0x00, + // 2292 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x39, 0xbb, 0x6f, 0x1b, 0xc9, + 0xf9, 0x5a, 0x91, 0x92, 0xc8, 0xa1, 0x1e, 0xd4, 0xd8, 0x27, 0x53, 0xb2, 0x8e, 0xa4, 0xf7, 0x7e, + 0x3e, 0xf0, 0x67, 0xc7, 0xe4, 0x49, 0x07, 0x04, 0x86, 0x93, 0x83, 0x41, 0x93, 0xb4, 0x4d, 0x3f, + 0x64, 0x66, 0x49, 0xeb, 0x00, 0xa7, 0x58, 0x0c, 0x77, 0x47, 0xe4, 0x44, 0xbb, 0x3b, 0xeb, 0x9d, + 0xe1, 0xda, 0x4c, 0x91, 0xfa, 0x9a, 0x00, 0x97, 0xee, 0x90, 0x26, 0x07, 0xa4, 0x09, 0xd2, 0x24, + 0x45, 0x70, 0x7f, 0x40, 0xaa, 0x4b, 0x80, 0x00, 0x97, 0x2e, 0xd5, 0x5d, 0x60, 0x17, 0x29, 0x02, + 0x24, 0x75, 0xba, 0x60, 0x66, 0x1f, 0x5c, 0xea, 0x65, 0x1a, 0xb6, 0xd3, 0x48, 0x3b, 0xdf, 0x6b, + 0xbe, 0x6f, 0xe6, 0x7b, 0x0e, 0xc1, 0x2e, 0x71, 0x38, 0xf6, 0x8c, 0x21, 0x22, 0x8e, 0xce, 0xb0, + 0x31, 0xf2, 0x08, 0x1f, 0xd7, 0x0c, 0xc3, 0xaf, 0xb9, 0x1e, 0xf5, 0x89, 0x89, 0xbd, 0x9a, 0xbf, + 0x13, 0x7f, 0x57, 0x5d, 0x8f, 0x72, 0x0a, 0x3f, 0x38, 0x81, 0xa7, 0x6a, 0x18, 0x7e, 0x35, 0xa6, + 0xf3, 0x77, 0xb6, 0xd6, 0x91, 0x4d, 0x1c, 0x5a, 0x93, 0x7f, 0x03, 0xbe, 0xad, 0xa2, 0x41, 0x99, + 0x4d, 0x59, 0xad, 0x8f, 0x18, 0xae, 0xf9, 0x3b, 0x7d, 0xcc, 0xd1, 0x4e, 0xcd, 0xa0, 0xc4, 0x09, + 0xf1, 0x1f, 0x86, 0x78, 0x2c, 0x84, 0x38, 0xc6, 0x84, 0x26, 0x02, 0x84, 0x74, 0x9b, 0x01, 0x9d, + 0x2e, 0x57, 0xb5, 0x60, 0x11, 0xa2, 0xce, 0x0f, 0xe8, 0x80, 0x06, 0x70, 0xf1, 0x15, 0x6d, 0x3c, + 0xa0, 0x74, 0x60, 0xe1, 0x9a, 0x5c, 0xf5, 0x47, 0x07, 0x35, 0x73, 0xe4, 0x21, 0x4e, 0x68, 0xb4, + 0x71, 0xe9, 0x28, 0x9e, 0x13, 0x1b, 0x33, 0x8e, 0x6c, 0x37, 0x22, 0x20, 0x7d, 0xa3, 0x66, 0x50, + 0x0f, 0xd7, 0x0c, 0x8b, 0x60, 0x87, 0x8b, 0x43, 0x09, 0xbe, 0x42, 0x82, 0x9a, 0x20, 0xb0, 0xc8, + 0x60, 0xc8, 0x03, 0x30, 0xab, 0x71, 0xec, 0x98, 0xd8, 0xb3, 0x49, 0x40, 0x3c, 0x59, 0x85, 0x0c, + 0x97, 0x4f, 0x3b, 0x77, 0x7f, 0xa7, 0xf6, 0x8c, 0x78, 0x91, 0xa9, 0xdb, 0x09, 0x31, 0x86, 0x37, + 0x76, 0x39, 0xad, 0x1d, 0xe2, 0x71, 0x68, 0xad, 0xfa, 0x9f, 0x0c, 0x28, 0x34, 0xa8, 0xc3, 0x46, + 0x36, 0xf6, 0xea, 0xa6, 0x49, 0x84, 0x49, 0x1d, 0x8f, 0xba, 0x94, 0x21, 0x0b, 0x9e, 0x07, 0x0b, + 0x9c, 0x70, 0x0b, 0x17, 0x94, 0xb2, 0x52, 0xc9, 0x6a, 0xc1, 0x02, 0x96, 0x41, 0xce, 0xc4, 0xcc, + 0xf0, 0x88, 0x2b, 0x88, 0x0b, 0xf3, 0x12, 0x97, 0x04, 0xc1, 0x4d, 0x90, 0x09, 0xd4, 0x22, 0x66, + 0x21, 0x25, 0xd1, 0x4b, 0x72, 0xdd, 0x36, 0xe1, 0x1d, 0xb0, 0x4a, 0x1c, 0xc2, 0x09, 0xb2, 0xf4, + 0x21, 0x16, 0xc6, 0x16, 0xd2, 0x65, 0xa5, 0x92, 0xdb, 0xdd, 0xaa, 0x92, 0xbe, 0x51, 0x15, 0xe7, + 0x53, 0x0d, 0x4f, 0xc5, 0xdf, 0xa9, 0xde, 0x95, 0x14, 0xb7, 0xd2, 0x5f, 0x7f, 0x5b, 0x9a, 0xd3, + 0x56, 0x42, 0xbe, 0x00, 0x08, 0x2f, 0x81, 0xe5, 0x01, 0x76, 0x30, 0x23, 0x4c, 0x1f, 0x22, 0x36, + 0x2c, 0x2c, 0x94, 0x95, 0xca, 0xb2, 0x96, 0x0b, 0x61, 0x77, 0x11, 0x1b, 0xc2, 0x12, 0xc8, 0xf5, + 0x89, 0x83, 0xbc, 0x71, 0x40, 0xb1, 0x28, 0x29, 0x40, 0x00, 0x92, 0x04, 0x0d, 0x00, 0x98, 0x8b, + 0x9e, 0x39, 0xba, 0xb8, 0xac, 0xc2, 0x52, 0xa8, 0x48, 0x70, 0x93, 0xd5, 0xe8, 0x26, 0xab, 0xbd, + 0xe8, 0x26, 0x6f, 0x65, 0x84, 0x22, 0x9f, 0x7f, 0x57, 0x52, 0xb4, 0xac, 0xe4, 0x13, 0x18, 0xb8, + 0x07, 0xf2, 0x23, 0xa7, 0x4f, 0x1d, 0x93, 0x38, 0x03, 0xdd, 0xc5, 0x1e, 0xa1, 0x66, 0x21, 0x23, + 0x45, 0x6d, 0x1e, 0x13, 0xd5, 0x0c, 0x9d, 0x26, 0x90, 0xf4, 0x85, 0x90, 0xb4, 0x16, 0x33, 0x77, + 0x24, 0x2f, 0xfc, 0x11, 0x80, 0x86, 0xe1, 0x4b, 0x95, 0xe8, 0x88, 0x47, 0x12, 0xb3, 0xb3, 0x4b, + 0xcc, 0x1b, 0x86, 0xdf, 0x0b, 0xb8, 0x43, 0x91, 0x3f, 0x06, 0x17, 0xb8, 0x87, 0x1c, 0x76, 0x80, + 0xbd, 0xa3, 0x72, 0xc1, 0xec, 0x72, 0xdf, 0x8b, 0x64, 0x4c, 0x0b, 0xbf, 0x0b, 0xca, 0x46, 0xe8, + 0x40, 0xba, 0x87, 0x4d, 0xc2, 0xb8, 0x47, 0xfa, 0x23, 0xc1, 0xab, 0x1f, 0x78, 0xc8, 0x90, 0x3e, + 0x92, 0x93, 0x4e, 0x50, 0x8c, 0xe8, 0xb4, 0x29, 0xb2, 0xdb, 0x21, 0x15, 0x7c, 0x04, 0xfe, 0xaf, + 0x6f, 0x51, 0xe3, 0x90, 0x09, 0xe5, 0xf4, 0x29, 0x49, 0x72, 0x6b, 0x9b, 0x30, 0x26, 0xa4, 0x2d, + 0x97, 0x95, 0x4a, 0x4a, 0xbb, 0x14, 0xd0, 0x76, 0xb0, 0xd7, 0x4c, 0x50, 0xf6, 0x12, 0x84, 0xf0, + 0x1a, 0x80, 0x43, 0xc2, 0x38, 0xf5, 0x88, 0x81, 0x2c, 0x1d, 0x3b, 0xdc, 0x23, 0x98, 0x15, 0x56, + 0x24, 0xfb, 0xfa, 0x04, 0xd3, 0x0a, 0x10, 0xf0, 0x1e, 0xb8, 0x74, 0xea, 0xa6, 0xba, 0x31, 0x44, + 0x8e, 0x83, 0xad, 0xc2, 0xaa, 0x34, 0xa5, 0x64, 0x9e, 0xb2, 0x67, 0x23, 0x20, 0x83, 0xe7, 0xc0, + 0x02, 0xa7, 0xae, 0xbe, 0x57, 0x58, 0x2b, 0x2b, 0x95, 0x15, 0x2d, 0xcd, 0xa9, 0xbb, 0x07, 0x3f, + 0x02, 0xe7, 0x7d, 0x64, 0x11, 0x13, 0x71, 0xea, 0x31, 0xdd, 0xa5, 0xcf, 0xb0, 0xa7, 0x1b, 0xc8, + 0x2d, 0xe4, 0x25, 0x0d, 0x9c, 0xe0, 0x3a, 0x02, 0xd5, 0x40, 0x2e, 0xbc, 0x02, 0xd6, 0x63, 0xa8, + 0xce, 0x30, 0x97, 0xe4, 0xeb, 0x92, 0x7c, 0x2d, 0x46, 0x74, 0x31, 0x17, 0xb4, 0xdb, 0x20, 0x8b, + 0x2c, 0x8b, 0x3e, 0xb3, 0x08, 0xe3, 0x05, 0x58, 0x4e, 0x55, 0xb2, 0xda, 0x04, 0x00, 0xb7, 0x40, + 0xc6, 0xc4, 0xce, 0x58, 0x22, 0xcf, 0x49, 0x64, 0xbc, 0x86, 0x17, 0x41, 0xd6, 0x16, 0x49, 0x84, + 0xa3, 0x43, 0x5c, 0x38, 0x5f, 0x56, 0x2a, 0x69, 0x2d, 0x63, 0x13, 0xa7, 0x2b, 0xd6, 0xb0, 0x0a, + 0xce, 0x49, 0x29, 0x3a, 0x71, 0xc4, 0x3d, 0xf9, 0x58, 0xf7, 0x91, 0xc5, 0x0a, 0xef, 0x95, 0x95, + 0x4a, 0x46, 0x5b, 0x97, 0xa8, 0x76, 0x88, 0xd9, 0x47, 0x16, 0xbb, 0x51, 0xf9, 0xec, 0xcb, 0xd2, + 0xdc, 0x17, 0x5f, 0x96, 0xe6, 0xfe, 0xfc, 0x87, 0x6b, 0x5b, 0x61, 0x66, 0x1d, 0x50, 0xbf, 0x1a, + 0x66, 0xe2, 0x6a, 0x83, 0x3a, 0x1c, 0x3b, 0xbc, 0xa0, 0xa8, 0x7f, 0x55, 0xc0, 0x85, 0x46, 0xec, + 0x12, 0x36, 0xf5, 0x91, 0xf5, 0x2e, 0x53, 0x4f, 0x1d, 0x64, 0x99, 0xb8, 0x13, 0x19, 0xec, 0xe9, + 0xd7, 0x08, 0xf6, 0x8c, 0x60, 0x13, 0x88, 0x1b, 0xe5, 0x57, 0xda, 0xf4, 0xef, 0x79, 0xb0, 0x1d, + 0xd9, 0xf4, 0x90, 0x9a, 0xe4, 0x80, 0x18, 0xe8, 0x5d, 0xe7, 0xd4, 0xd8, 0xd7, 0xd2, 0x33, 0xf8, + 0xda, 0xc2, 0xeb, 0xf9, 0xda, 0xe2, 0x0c, 0xbe, 0xb6, 0x74, 0x96, 0xaf, 0x65, 0xce, 0xf2, 0xb5, + 0xec, 0x6c, 0xbe, 0x06, 0x4e, 0xf3, 0xb5, 0xf9, 0x82, 0xa2, 0xfe, 0x4a, 0x01, 0xe7, 0x5b, 0x4f, + 0x47, 0xc4, 0xa7, 0x6f, 0xe9, 0xa4, 0xef, 0x83, 0x15, 0x9c, 0x90, 0xc7, 0x0a, 0xa9, 0x72, 0xaa, + 0x92, 0xdb, 0xbd, 0x5c, 0x0d, 0x2f, 0x3e, 0x6e, 0x25, 0xa2, 0xdb, 0x4f, 0xee, 0xae, 0x4d, 0xf3, + 0x4a, 0x0d, 0xff, 0xa8, 0x80, 0x2d, 0x91, 0x17, 0x06, 0x58, 0xc3, 0xcf, 0x90, 0x67, 0x36, 0xb1, + 0x43, 0x6d, 0xf6, 0xc6, 0x7a, 0xaa, 0x60, 0xc5, 0x94, 0x92, 0x74, 0x4e, 0x75, 0x64, 0x9a, 0x52, + 0x4f, 0x49, 0x23, 0x80, 0x3d, 0x5a, 0x37, 0x4d, 0x58, 0x01, 0xf9, 0x09, 0x8d, 0x27, 0x62, 0x4c, + 0xb8, 0xbe, 0x20, 0x5b, 0x8d, 0xc8, 0x64, 0xe4, 0xe1, 0x1b, 0xc5, 0xb3, 0x5d, 0x5b, 0xfd, 0xa7, + 0x02, 0xf2, 0x77, 0x2c, 0xda, 0x47, 0x56, 0xd7, 0x42, 0x6c, 0x28, 0x72, 0xe6, 0x58, 0x84, 0x94, + 0x87, 0xc3, 0x62, 0x25, 0xd5, 0x9f, 0x39, 0xa4, 0x04, 0x9b, 0x2c, 0x9f, 0x37, 0xc1, 0x7a, 0x5c, + 0x3e, 0x62, 0x07, 0x97, 0xd6, 0xde, 0x3a, 0xf7, 0xe2, 0xdb, 0xd2, 0x5a, 0x14, 0x4c, 0x0d, 0xe9, + 0xec, 0x4d, 0x6d, 0xcd, 0x98, 0x02, 0x98, 0xb0, 0x08, 0x72, 0xa4, 0x6f, 0xe8, 0x0c, 0x3f, 0xd5, + 0x9d, 0x91, 0x2d, 0x63, 0x23, 0xad, 0x65, 0x49, 0xdf, 0xe8, 0xe2, 0xa7, 0x7b, 0x23, 0x1b, 0x7e, + 0x0c, 0x36, 0xa2, 0xa6, 0x52, 0x78, 0x93, 0x2e, 0xf8, 0xc5, 0x71, 0x79, 0x32, 0x5c, 0x96, 0xb5, + 0x73, 0x11, 0x76, 0x1f, 0x59, 0x62, 0xb3, 0xba, 0x69, 0x7a, 0xea, 0xbf, 0x16, 0xc0, 0x62, 0x07, + 0x79, 0xc8, 0x66, 0xb0, 0x07, 0xd6, 0x38, 0xb6, 0x5d, 0x0b, 0x71, 0xac, 0x07, 0xad, 0x49, 0x68, + 0xe9, 0x55, 0xd9, 0xb2, 0x24, 0x3b, 0xb6, 0x6a, 0xa2, 0x47, 0xf3, 0x77, 0xaa, 0x0d, 0x09, 0xed, + 0x72, 0xc4, 0xb1, 0xb6, 0x1a, 0xc9, 0x08, 0x80, 0xf0, 0x3a, 0x28, 0x70, 0x6f, 0xc4, 0xf8, 0xa4, + 0x69, 0x98, 0x54, 0xcb, 0xe0, 0xae, 0x37, 0x22, 0x7c, 0x50, 0x67, 0xe3, 0x2a, 0x79, 0x72, 0x7f, + 0x90, 0x7a, 0x93, 0xfe, 0xc0, 0x04, 0xdb, 0x4c, 0x5c, 0xaa, 0x6e, 0x63, 0x2e, 0xab, 0xb8, 0x6b, + 0x61, 0x87, 0xb0, 0x61, 0x24, 0x7c, 0x71, 0x76, 0xe1, 0x9b, 0x52, 0xd0, 0x43, 0x21, 0x47, 0x8b, + 0xc4, 0x84, 0xbb, 0x34, 0x40, 0xf1, 0xe4, 0x5d, 0x62, 0xc3, 0x97, 0xa4, 0xe1, 0x17, 0x4f, 0x10, + 0x11, 0x5b, 0xcf, 0xc0, 0x87, 0x89, 0x6e, 0x43, 0x44, 0x93, 0x2e, 0x1d, 0x59, 0xf7, 0xf0, 0x40, + 0x94, 0x64, 0x14, 0x34, 0x1e, 0x18, 0xc7, 0x1d, 0x53, 0xe8, 0xd3, 0x62, 0x62, 0x48, 0x38, 0x35, + 0x71, 0xc2, 0xb6, 0x52, 0x9d, 0x34, 0x25, 0x71, 0x6c, 0x6a, 0x09, 0x59, 0xb7, 0x31, 0x16, 0x51, + 0x94, 0x68, 0x4c, 0xb0, 0x4b, 0x8d, 0xa1, 0xcc, 0x49, 0x29, 0x6d, 0x35, 0x6e, 0x42, 0x5a, 0x02, + 0x0a, 0x9f, 0x80, 0xab, 0xce, 0xc8, 0xee, 0x63, 0x4f, 0xa7, 0x07, 0x01, 0xa1, 0x8c, 0x3c, 0xc6, + 0x91, 0xc7, 0x75, 0x0f, 0x1b, 0x98, 0xf8, 0xe2, 0xc6, 0x03, 0xcd, 0x99, 0xec, 0x8b, 0x52, 0xda, + 0xe5, 0x80, 0xe5, 0xd1, 0x81, 0x94, 0xc1, 0x7a, 0xb4, 0x2b, 0xc8, 0xb5, 0x88, 0x3a, 0x50, 0x8c, + 0xc1, 0x36, 0xb8, 0x64, 0xa3, 0xe7, 0x7a, 0xec, 0xcc, 0x42, 0x71, 0xec, 0xb0, 0x11, 0xd3, 0x27, + 0xc9, 0x3c, 0xec, 0x8d, 0x8a, 0x36, 0x7a, 0xde, 0x09, 0xe9, 0x1a, 0x11, 0xd9, 0x7e, 0x4c, 0x75, + 0x2f, 0x9d, 0x49, 0xe7, 0x17, 0xee, 0xa5, 0x33, 0x0b, 0xf9, 0xc5, 0x7b, 0xe9, 0x4c, 0x26, 0x9f, + 0x55, 0xff, 0x1f, 0x64, 0x65, 0x5c, 0xd7, 0x8d, 0x43, 0x26, 0xb3, 0xbb, 0x69, 0x7a, 0x98, 0x31, + 0xcc, 0x0a, 0x4a, 0x98, 0xdd, 0x23, 0x80, 0xca, 0xc1, 0xe6, 0x69, 0x13, 0x03, 0x83, 0x9f, 0x82, + 0x25, 0x17, 0xcb, 0x76, 0x56, 0x32, 0xe6, 0x76, 0x3f, 0xa9, 0xce, 0x30, 0xea, 0x55, 0x4f, 0x13, + 0xa8, 0x45, 0xd2, 0x54, 0x6f, 0x32, 0xa7, 0x1c, 0xe9, 0x15, 0x18, 0xdc, 0x3f, 0xba, 0xe9, 0x0f, + 0x5f, 0x6b, 0xd3, 0x23, 0xf2, 0x26, 0x7b, 0x5e, 0x05, 0xb9, 0x7a, 0x60, 0xf6, 0x03, 0x51, 0xba, + 0x8e, 0x1d, 0xcb, 0x72, 0xf2, 0x58, 0xf6, 0xc0, 0x6a, 0xd8, 0xfc, 0xf5, 0xa8, 0xcc, 0x4d, 0xf0, + 0x7d, 0x00, 0xc2, 0xae, 0x51, 0xe4, 0xb4, 0x20, 0xbb, 0x67, 0x43, 0x48, 0xdb, 0x9c, 0xaa, 0xe8, + 0xf3, 0x53, 0x15, 0x5d, 0x56, 0x0d, 0x0a, 0x36, 0xf7, 0x93, 0x55, 0x57, 0x16, 0x90, 0x0e, 0x32, + 0x0e, 0x31, 0x67, 0x50, 0x03, 0x69, 0x59, 0x5d, 0x03, 0x73, 0xaf, 0x9f, 0x6a, 0xae, 0xbf, 0x53, + 0x3d, 0x4d, 0x48, 0x13, 0x71, 0x14, 0xc6, 0x80, 0x94, 0xa5, 0xfe, 0x42, 0x01, 0x85, 0xfb, 0x78, + 0x5c, 0x67, 0x8c, 0x0c, 0x1c, 0x1b, 0x3b, 0x5c, 0x44, 0x1f, 0x32, 0xb0, 0xf8, 0x84, 0x1f, 0x80, + 0x95, 0xd8, 0xf1, 0x64, 0xf2, 0x54, 0x64, 0xf2, 0x5c, 0x8e, 0x80, 0xe2, 0x9c, 0xe0, 0x0d, 0x00, + 0x5c, 0x0f, 0xfb, 0xba, 0xa1, 0x1f, 0xe2, 0xb1, 0xb4, 0x29, 0xb7, 0xbb, 0x9d, 0x4c, 0x8a, 0xc1, + 0xfc, 0x59, 0xed, 0x8c, 0xfa, 0x16, 0x31, 0xee, 0xe3, 0xb1, 0x96, 0x11, 0xf4, 0x8d, 0xfb, 0x78, + 0x2c, 0xaa, 0xa0, 0x6c, 0x52, 0x64, 0x26, 0x4b, 0x69, 0xc1, 0x42, 0xfd, 0xa5, 0x02, 0x2e, 0xc4, + 0x06, 0x44, 0xf7, 0xd5, 0x19, 0xf5, 0x05, 0x47, 0xf2, 0xfc, 0x94, 0xe9, 0x8e, 0xe8, 0x98, 0xb6, + 0xf3, 0x27, 0x68, 0x7b, 0x13, 0x2c, 0xc7, 0xa9, 0x44, 0xe8, 0x9b, 0x9a, 0x41, 0xdf, 0x5c, 0xc4, + 0x71, 0x1f, 0x8f, 0xd5, 0x9f, 0x25, 0x74, 0xbb, 0x35, 0x4e, 0xb8, 0xb0, 0xf7, 0x0a, 0xdd, 0xe2, + 0x6d, 0x93, 0xba, 0x19, 0x49, 0xfe, 0x63, 0x06, 0xa4, 0x8e, 0x1b, 0xa0, 0xfe, 0x45, 0x01, 0x1b, + 0xc9, 0x5d, 0x59, 0x8f, 0x76, 0xbc, 0x91, 0x83, 0xf7, 0x77, 0xcf, 0xda, 0xff, 0x26, 0xc8, 0xb8, + 0x82, 0x4a, 0xe7, 0x2c, 0xbc, 0xa2, 0xd9, 0x4a, 0xf6, 0x92, 0xe4, 0xea, 0x89, 0x10, 0x5f, 0x9d, + 0x32, 0x80, 0x85, 0x27, 0xf7, 0xd1, 0x4c, 0x41, 0x97, 0x08, 0x28, 0x6d, 0x25, 0x69, 0x33, 0x53, + 0xbf, 0x52, 0x00, 0x3c, 0x9e, 0xad, 0xe0, 0xf7, 0x00, 0x9c, 0xca, 0x79, 0x49, 0xff, 0xcb, 0xbb, + 0x89, 0x2c, 0x27, 0x4f, 0x2e, 0xf6, 0xa3, 0xf9, 0x84, 0x1f, 0xc1, 0x1f, 0x00, 0xe0, 0xca, 0x4b, + 0x9c, 0xf9, 0xa6, 0xb3, 0x6e, 0xf4, 0x09, 0x4b, 0x20, 0xf7, 0x13, 0x4a, 0x9c, 0xe4, 0x83, 0x45, + 0x4a, 0x03, 0x02, 0x14, 0xbc, 0x45, 0xa8, 0x3f, 0x57, 0x26, 0x29, 0x31, 0xcc, 0xd6, 0x75, 0xcb, + 0x0a, 0x7b, 0x40, 0xe8, 0x82, 0xa5, 0x28, 0xdf, 0x07, 0xe1, 0xba, 0x7d, 0x62, 0x4d, 0x6a, 0x62, + 0x43, 0x96, 0xa5, 0xeb, 0xe2, 0xc4, 0x7f, 0xfb, 0x5d, 0xe9, 0xea, 0x80, 0xf0, 0xe1, 0xa8, 0x5f, + 0x35, 0xa8, 0x1d, 0x3e, 0x50, 0x85, 0xff, 0xae, 0x31, 0xf3, 0xb0, 0xc6, 0xc7, 0x2e, 0x66, 0x11, + 0x0f, 0xfb, 0xcd, 0x3f, 0x7e, 0x7f, 0x45, 0xd1, 0xa2, 0x6d, 0x54, 0x13, 0xe4, 0xe3, 0x19, 0x04, + 0x73, 0x64, 0x22, 0x8e, 0x20, 0x04, 0x69, 0x07, 0xd9, 0x51, 0x93, 0x29, 0xbf, 0x67, 0xe8, 0x31, + 0xb7, 0x40, 0xc6, 0x0e, 0x25, 0x84, 0x53, 0x47, 0xbc, 0x56, 0x7f, 0xb7, 0x08, 0xca, 0xd1, 0x36, + 0xed, 0xe0, 0x6d, 0x86, 0xfc, 0x34, 0x68, 0xc1, 0x45, 0xe7, 0x24, 0xea, 0x37, 0x3b, 0xe1, 0xbd, + 0x47, 0x79, 0x3b, 0xef, 0x3d, 0xf3, 0xaf, 0x7c, 0xef, 0x49, 0xbd, 0xe2, 0xbd, 0x27, 0xfd, 0xf6, + 0xde, 0x7b, 0x16, 0xde, 0xfa, 0x7b, 0xcf, 0xe2, 0x3b, 0x7a, 0xef, 0x59, 0xfa, 0x9f, 0xbc, 0xf7, + 0x64, 0xde, 0xea, 0x7b, 0x4f, 0xf6, 0xcd, 0xde, 0x7b, 0xc0, 0x1b, 0xbd, 0xf7, 0xe4, 0x66, 0x7b, + 0xef, 0x09, 0xb2, 0xba, 0x83, 0xa5, 0x65, 0x22, 0xeb, 0x2e, 0x4b, 0xbe, 0xe5, 0x09, 0xb0, 0x6d, + 0xaa, 0x5f, 0xcd, 0x83, 0x0d, 0x39, 0x6e, 0x77, 0x87, 0xc8, 0x15, 0x1e, 0x30, 0x89, 0x93, 0x78, + 0x86, 0x57, 0x66, 0x98, 0xe1, 0xe7, 0x5f, 0x6f, 0x86, 0x4f, 0xcd, 0x30, 0xc3, 0xa7, 0xcf, 0x9a, + 0xe1, 0x17, 0xce, 0x9a, 0xe1, 0x17, 0x67, 0x9b, 0xe1, 0x97, 0x4e, 0x99, 0xe1, 0xa1, 0x0a, 0x96, + 0x5d, 0x8f, 0x50, 0x51, 0x2c, 0x12, 0x0f, 0x06, 0x53, 0x30, 0xb5, 0x04, 0x72, 0x71, 0xa6, 0x31, + 0x19, 0xcc, 0x83, 0x14, 0x31, 0xa3, 0xce, 0x54, 0x7c, 0xaa, 0x3b, 0xe0, 0x42, 0x3d, 0x52, 0x1d, + 0x9b, 0xc9, 0x31, 0x1b, 0x6e, 0x80, 0xc5, 0x60, 0xd4, 0x0d, 0xe9, 0xc3, 0xd5, 0x95, 0x3f, 0x29, + 0x60, 0x25, 0xee, 0x28, 0x86, 0x88, 0x61, 0x58, 0x04, 0x5b, 0x8d, 0x47, 0x7b, 0xdd, 0xc7, 0x0f, + 0x5b, 0x9a, 0xde, 0xb9, 0x5b, 0xef, 0xb6, 0xf4, 0xc7, 0x7b, 0xdd, 0x4e, 0xab, 0xd1, 0xbe, 0xdd, + 0x6e, 0x35, 0xf3, 0x73, 0xf0, 0x7d, 0xb0, 0x79, 0x04, 0xaf, 0xb5, 0xee, 0xb4, 0xbb, 0xbd, 0x96, + 0xd6, 0x6a, 0xe6, 0x95, 0x13, 0xd8, 0xdb, 0x7b, 0xed, 0x5e, 0xbb, 0xfe, 0xa0, 0xfd, 0xa4, 0xd5, + 0xcc, 0xcf, 0xc3, 0x8b, 0xe0, 0xc2, 0x11, 0xfc, 0x83, 0xfa, 0xe3, 0xbd, 0xc6, 0xdd, 0x56, 0x33, + 0x9f, 0x82, 0x5b, 0x60, 0xe3, 0x08, 0xb2, 0xdb, 0x7b, 0xd4, 0xe9, 0xb4, 0x9a, 0xf9, 0xf4, 0x09, + 0xb8, 0x66, 0xeb, 0x41, 0xab, 0xd7, 0x6a, 0xe6, 0x17, 0xb6, 0xd2, 0x9f, 0xfd, 0xba, 0x38, 0x77, + 0xeb, 0xd3, 0xaf, 0x5f, 0x14, 0x95, 0x6f, 0x5e, 0x14, 0x95, 0xbf, 0xbf, 0x28, 0x2a, 0x9f, 0xbf, + 0x2c, 0xce, 0x7d, 0xf3, 0xb2, 0x38, 0xf7, 0xb7, 0x97, 0xc5, 0xb9, 0x27, 0x9f, 0x1c, 0xaf, 0x22, + 0x93, 0x2a, 0x7d, 0x2d, 0xfe, 0xd9, 0xc0, 0xff, 0x7e, 0xed, 0xf9, 0xf4, 0x6f, 0x36, 0xb2, 0xc0, + 0xf4, 0x17, 0x65, 0x82, 0xf8, 0xf8, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x33, 0xf8, 0x36, 0x6b, + 0xe4, 0x19, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -3194,6 +3208,13 @@ func (m *ConsumerInitializationParameters) MarshalToSizedBuffer(dAtA []byte) (in _ = i var l int _ = l + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x62 + } if len(m.DistributionTransmissionChannel) > 0 { i -= len(m.DistributionTransmissionChannel) copy(dAtA[i:], m.DistributionTransmissionChannel) @@ -3963,6 +3984,10 @@ func (m *ConsumerInitializationParameters) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovProvider(uint64(l)) + } return n } @@ -7844,6 +7869,38 @@ func (m *ConsumerInitializationParameters) Unmarshal(dAtA []byte) error { } m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + 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 ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) From d496224fa7ed7d57682310382f5ff314995d656d Mon Sep 17 00:00:00 2001 From: mpoke Date: Mon, 4 Nov 2024 16:36:48 +0100 Subject: [PATCH 02/25] add message validation --- x/ccv/provider/types/msg.go | 13 ++++++ x/ccv/provider/types/msg_test.go | 71 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 91a5282c4f..0e7445e42c 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" @@ -592,6 +593,10 @@ func ValidateInitializationParameters(initializationParameters ConsumerInitializ return errorsmod.Wrapf(ErrInvalidConsumerInitializationParameters, "UnbondingPeriod: %s", err.Error()) } + if err := ValidateConnectionIdentifier(initializationParameters.ConnectionId); err != nil { + return errorsmod.Wrapf(ErrInvalidConsumerInitializationParameters, "ConnectionId: %s", err.Error()) + } + return nil } @@ -633,3 +638,11 @@ func ValidateInitialHeight(initialHeight clienttypes.Height, chainID string) err } return nil } + +func ValidateConnectionIdentifier(connId string) error { + // accept empty string as valid + if connId == "" { + return nil + } + return ibchost.ConnectionIdentifierValidator(connId) +} diff --git a/x/ccv/provider/types/msg_test.go b/x/ccv/provider/types/msg_test.go index f1eaa3124a..149e291c70 100644 --- a/x/ccv/provider/types/msg_test.go +++ b/x/ccv/provider/types/msg_test.go @@ -166,6 +166,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: true, }, @@ -183,6 +184,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -200,6 +202,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -217,6 +220,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: true, }, @@ -234,6 +238,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -251,6 +256,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -268,6 +274,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -285,6 +292,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 0, HistoricalEntries: 10000, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -302,6 +310,7 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 0, DistributionTransmissionChannel: "", + ConnectionId: "", }, valid: false, }, @@ -319,6 +328,25 @@ func TestValidateInitializationParameters(t *testing.T) { BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, DistributionTransmissionChannel: coolStr, + ConnectionId: "", + }, + valid: false, + }, + { + name: "invalid - ConnectionId too long", + params: types.ConsumerInitializationParameters{ + InitialHeight: clienttypes.NewHeight(3, 4), + GenesisHash: []byte{0x01}, + BinaryHash: []byte{0x01}, + SpawnTime: now, + UnbondingPeriod: time.Duration(100000000000), + CcvTimeoutPeriod: time.Duration(100000000000), + TransferTimeoutPeriod: time.Duration(100000000000), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + HistoricalEntries: 10000, + DistributionTransmissionChannel: "", + ConnectionId: coolStr, }, valid: false, }, @@ -714,3 +742,46 @@ func TestValidateInitialHeight(t *testing.T) { } } } + +func TestValidateConnectionIdentifier(t *testing.T) { + testCases := []struct { + name string + connId string + expPass bool + }{ + { + name: "valid connection ID", + connId: "connection-0", + expPass: true, + }, + { + name: "valid empty connection ID", + connId: "", + expPass: true, + }, + { + name: "invalid connection ID with /", + connId: "invalid-connection-id/", + expPass: false, + }, + { + name: "invalid connection ID with special characters", + connId: "connection-@#", + expPass: false, + }, + { + name: "invalid connection ID with spaces", + connId: "connection id", + expPass: false, + }, + } + + for _, tc := range testCases { + err := types.ValidateConnectionIdentifier(tc.connId) + if tc.expPass { + require.NoError(t, err, "valid case: '%s' should not return error. got %w", tc.name, err) + } else { + require.Error(t, err, "invalid case: '%s' must return error but got none", tc.name) + } + } +} From 29c8d9a5f246aeaa3d84ad5959e8d6b49c26b76e Mon Sep 17 00:00:00 2001 From: mpoke Date: Mon, 4 Nov 2024 17:08:34 +0100 Subject: [PATCH 03/25] add preCCV and connection_id to ProviderInfo --- app/consumer-democracy/app.go | 3 +- .../ccv/consumer/v1/genesis.proto | 5 +- .../ccv/v1/shared_consumer.proto | 19 +- x/ccv/consumer/keeper/genesis.go | 4 +- x/ccv/consumer/types/genesis.pb.go | 160 +++++-------- x/ccv/consumer/types/genesis_test.go | 14 +- x/ccv/types/shared_consumer.pb.go | 216 +++++++++++++----- 7 files changed, 247 insertions(+), 174 deletions(-) diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index cef5aa8f9c..08c0ed1d5d 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -38,6 +38,7 @@ import ( "cosmossdk.io/x/feegrant" feegrantkeeper "cosmossdk.io/x/feegrant/keeper" feegrantmodule "cosmossdk.io/x/feegrant/module" + // add mint "cosmossdk.io/x/upgrade" upgradekeeper "cosmossdk.io/x/upgrade/keeper" @@ -695,7 +696,7 @@ func New( consumerGenesis := consumertypes.GenesisState{} appCodec.MustUnmarshalJSON(appState[consumertypes.ModuleName], &consumerGenesis) - consumerGenesis.PreCCV = true + consumerGenesis.Provider.PreCCV = true app.ConsumerKeeper.InitGenesis(sdkCtx, &consumerGenesis) app.Logger().Info("start to run module migrations...") diff --git a/proto/interchain_security/ccv/consumer/v1/genesis.proto b/proto/interchain_security/ccv/consumer/v1/genesis.proto index 69a765b8e2..9007af0f44 100644 --- a/proto/interchain_security/ccv/consumer/v1/genesis.proto +++ b/proto/interchain_security/ccv/consumer/v1/genesis.proto @@ -20,6 +20,9 @@ import "tendermint/abci/types.proto"; // Note: this type is only used on consumer side and references shared types with // provider message GenesisState { + // Reserve 13th slot for removed preCCV field + reserved 13; + // ConsumerParams is a shared type with provider module interchain_security.ccv.v1.ConsumerParams params = 1 [ (gogoproto.nullable) = false ]; @@ -50,8 +53,6 @@ message GenesisState { // LastTransmissionBlockHeight nil on new chain, filled in on restart. LastTransmissionBlockHeight last_transmission_block_height = 12 [ (gogoproto.nullable) = false ]; - // flag indicating whether the consumer CCV module starts in pre-CCV state - bool preCCV = 13; interchain_security.ccv.v1.ProviderInfo provider = 14 [ (gogoproto.nullable) = false ]; } diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index d8dad14df7..44d5d9dc5e 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -87,18 +87,29 @@ message ConsumerParams { message ConsumerGenesisState { ConsumerParams params = 1 [ (gogoproto.nullable) = false ]; ProviderInfo provider = 2 [ (gogoproto.nullable) = false ]; - // true for new chain, false for chain restart. - bool new_chain = 3; // TODO:Check if this is really needed + // True for new chain, false for chain restart. + // This is needed and always set to true; otherwise, new_chain in the consumer + // genesis state will default to false + bool new_chain = 3; } // ProviderInfo defines all information a consumer needs from a provider // Shared data type between provider and consumer message ProviderInfo { - // ProviderClientState filled in on new chain, nil on restart. + // The client state for the provider client filled in on new chain, nil on restart. + // If connection_id != "", then client_state is ignored. ibc.lightclients.tendermint.v1.ClientState client_state = 1; - // ProviderConsensusState filled in on new chain, nil on restart. + // The consensus state for the provider client filled in on new chain, nil on restart. + // If connection_id != "", then consensus_state is ignored. ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; // InitialValset filled in on new chain and on restart. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 [ (gogoproto.nullable) = false ]; + // The ID of the connection end on the consumer chain on top of which the + // CCV channel will be established. If connection_id == "", a new client of + // the provider chain and a new connection on top of this client are created. + // The new client is initialized using client_state and consensus_state. + string connection_id = 4; + // Flag indicating whether the consumer CCV module starts in pre-CCV state + bool preCCV = 5; } diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index e45a5fa892..b62d6a62fe 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -24,7 +24,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V // Once the provider validator set starts validating blocks, the consumer CCV module // will take over proof of stake capabilities, but the standalone staking keeper will // stick around for slashing/jailing purposes. - if state.PreCCV { + if state.Provider.PreCCV { k.SetPreCCVTrue(ctx) k.MarkAsPrevStandaloneChain(ctx) k.SetInitialValSet(ctx, state.Provider.InitialValSet) @@ -106,7 +106,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V k.SetProviderClientID(ctx, state.ProviderClientId) } - if state.PreCCV { + if state.Provider.PreCCV { return []abci.ValidatorUpdate{} } diff --git a/x/ccv/consumer/types/genesis.pb.go b/x/ccv/consumer/types/genesis.pb.go index 34eeb43cfa..88869fa300 100644 --- a/x/ccv/consumer/types/genesis.pb.go +++ b/x/ccv/consumer/types/genesis.pb.go @@ -59,9 +59,7 @@ type GenesisState struct { PendingConsumerPackets ConsumerPacketDataList `protobuf:"bytes,11,opt,name=pending_consumer_packets,json=pendingConsumerPackets,proto3" json:"pending_consumer_packets"` // LastTransmissionBlockHeight nil on new chain, filled in on restart. LastTransmissionBlockHeight LastTransmissionBlockHeight `protobuf:"bytes,12,opt,name=last_transmission_block_height,json=lastTransmissionBlockHeight,proto3" json:"last_transmission_block_height"` - // flag indicating whether the consumer CCV module starts in pre-CCV state - PreCCV bool `protobuf:"varint,13,opt,name=preCCV,proto3" json:"preCCV,omitempty"` - Provider types.ProviderInfo `protobuf:"bytes,14,opt,name=provider,proto3" json:"provider"` + Provider types.ProviderInfo `protobuf:"bytes,14,opt,name=provider,proto3" json:"provider"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -184,13 +182,6 @@ func (m *GenesisState) GetLastTransmissionBlockHeight() LastTransmissionBlockHei return LastTransmissionBlockHeight{} } -func (m *GenesisState) GetPreCCV() bool { - if m != nil { - return m.PreCCV - } - return false -} - func (m *GenesisState) GetProvider() types.ProviderInfo { if m != nil { return m.Provider @@ -463,64 +454,64 @@ func init() { } var fileDescriptor_2db73a6057a27482 = []byte{ - // 912 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcf, 0x6f, 0x23, 0x35, - 0x14, 0xee, 0xb4, 0xdd, 0x90, 0xb8, 0xed, 0x6e, 0xd7, 0x5d, 0xa2, 0xa1, 0x11, 0x69, 0x14, 0x84, - 0x14, 0xf1, 0xc3, 0x43, 0x8a, 0x58, 0x21, 0x21, 0x10, 0x24, 0x95, 0x68, 0x50, 0x11, 0x55, 0xda, - 0x0d, 0xd2, 0x5e, 0x46, 0x8e, 0xc7, 0x3b, 0xb1, 0x76, 0xc6, 0x1e, 0x8d, 0x9d, 0x09, 0x15, 0xe2, - 0xc2, 0x95, 0xcb, 0xfe, 0x59, 0x7b, 0xdc, 0x03, 0x07, 0x4e, 0x80, 0xda, 0x7f, 0x04, 0xd9, 0xe3, - 0x99, 0x24, 0x34, 0xed, 0xe6, 0x16, 0xcf, 0x7b, 0xef, 0xfb, 0xde, 0xfb, 0xde, 0x7b, 0x76, 0x40, - 0x97, 0x71, 0x45, 0x53, 0x32, 0xc1, 0x8c, 0xfb, 0x92, 0x92, 0x69, 0xca, 0xd4, 0x95, 0x47, 0x48, - 0xe6, 0x11, 0xc1, 0xe5, 0x34, 0xa6, 0xa9, 0x97, 0x75, 0xbd, 0x90, 0x72, 0x2a, 0x99, 0x44, 0x49, - 0x2a, 0x94, 0x80, 0x1f, 0xac, 0x08, 0x41, 0x84, 0x64, 0xa8, 0x08, 0x41, 0x59, 0xf7, 0xf0, 0xb3, - 0xbb, 0x70, 0xb3, 0xae, 0x27, 0x27, 0x38, 0xa5, 0x81, 0x5f, 0xba, 0x1b, 0xd8, 0x43, 0x8f, 0x8d, - 0x89, 0x17, 0xb1, 0x70, 0xa2, 0x48, 0xc4, 0x28, 0x57, 0xd2, 0x53, 0x94, 0x07, 0x34, 0x8d, 0x19, - 0x57, 0x3a, 0x6a, 0x7e, 0xb2, 0x01, 0x4f, 0x42, 0x11, 0x0a, 0xf3, 0xd3, 0xd3, 0xbf, 0xec, 0xd7, - 0x0f, 0xef, 0x21, 0x9e, 0xb1, 0x94, 0x5a, 0xb7, 0xa3, 0x50, 0x88, 0x30, 0xa2, 0x9e, 0x39, 0x8d, - 0xa7, 0x2f, 0x3c, 0xc5, 0x62, 0x2a, 0x15, 0x8e, 0x13, 0xeb, 0xd0, 0x58, 0x60, 0xc7, 0x63, 0xc2, - 0x3c, 0x75, 0x95, 0x50, 0x2b, 0x41, 0xfb, 0xcf, 0x1a, 0xd8, 0xfd, 0x3e, 0x17, 0xe5, 0x42, 0x61, - 0x45, 0xe1, 0x29, 0xa8, 0x24, 0x38, 0xc5, 0xb1, 0x74, 0x9d, 0x96, 0xd3, 0xd9, 0x39, 0xfe, 0x08, - 0xdd, 0x25, 0x52, 0xd6, 0x45, 0x7d, 0x5b, 0xf8, 0xb9, 0x89, 0xe8, 0x6d, 0xbf, 0xfe, 0xfb, 0x68, - 0x63, 0x68, 0xe3, 0xe1, 0x27, 0x00, 0x26, 0xa9, 0xc8, 0x58, 0x40, 0x53, 0x3f, 0x17, 0xc2, 0x67, - 0x81, 0xbb, 0xd9, 0x72, 0x3a, 0xb5, 0xe1, 0x7e, 0x61, 0xe9, 0x1b, 0xc3, 0x20, 0x80, 0x08, 0x1c, - 0xcc, 0xbd, 0x27, 0x98, 0x73, 0x1a, 0x69, 0xf7, 0x2d, 0xe3, 0xfe, 0xb8, 0x74, 0xcf, 0x2d, 0x83, - 0x00, 0x36, 0x40, 0x8d, 0xd3, 0x99, 0x6f, 0xf2, 0x72, 0xb7, 0x5b, 0x4e, 0xa7, 0x3a, 0xac, 0x72, - 0x3a, 0xeb, 0xeb, 0x33, 0x24, 0xe0, 0xdd, 0xff, 0x53, 0x4b, 0x5d, 0x9d, 0xfb, 0xc0, 0xd4, 0xf4, - 0x31, 0x62, 0x63, 0x82, 0x16, 0x3b, 0x84, 0x16, 0x7a, 0xa2, 0xeb, 0x32, 0x5f, 0x8d, 0x20, 0xbd, - 0x4d, 0xd7, 0x19, 0x1e, 0x2c, 0xa7, 0x9b, 0x2b, 0x15, 0x01, 0x77, 0x4e, 0x22, 0xb8, 0xa4, 0x5c, - 0x4e, 0xa5, 0xe5, 0xa9, 0x18, 0x1e, 0xf4, 0x56, 0x9e, 0x22, 0x6c, 0x4e, 0x55, 0x2f, 0xa9, 0x96, - 0x6c, 0x30, 0x04, 0xfb, 0x31, 0x56, 0xd3, 0x94, 0xf1, 0xd0, 0x4f, 0x30, 0x79, 0x49, 0x95, 0x74, - 0xdf, 0x69, 0x6d, 0x75, 0x76, 0x8e, 0x9f, 0xa2, 0x35, 0xc6, 0x18, 0xfd, 0x68, 0x83, 0x47, 0x17, - 0xfd, 0x73, 0x13, 0x6e, 0xbb, 0xf5, 0xa8, 0x40, 0xcd, 0xbf, 0x4a, 0x78, 0x0e, 0x1e, 0x31, 0xce, - 0x14, 0xc3, 0x91, 0x9f, 0xe1, 0xc8, 0x97, 0x54, 0xb9, 0x55, 0xc3, 0xd3, 0x5a, 0x4c, 0x5e, 0x0f, - 0x12, 0x1a, 0xe1, 0x88, 0x05, 0x58, 0x89, 0xf4, 0x59, 0x12, 0xe8, 0xfc, 0x2b, 0x1a, 0xd1, 0x75, - 0x86, 0x7b, 0x16, 0x60, 0x84, 0xa3, 0x0b, 0xaa, 0xe0, 0x6f, 0xe0, 0x70, 0x42, 0xb5, 0x08, 0xbe, - 0x12, 0x1a, 0x53, 0x52, 0xe5, 0x4f, 0x4d, 0x84, 0xee, 0x70, 0xcd, 0x80, 0x7f, 0xb5, 0x56, 0x11, - 0xa7, 0x06, 0xe6, 0x52, 0x8c, 0x0c, 0x48, 0xce, 0x3a, 0x38, 0xb1, 0x95, 0xd4, 0x27, 0xab, 0xac, - 0x01, 0xfc, 0xdd, 0x01, 0xef, 0x8b, 0xa9, 0x92, 0x0a, 0xf3, 0x40, 0xab, 0x17, 0x88, 0x19, 0xd7, - 0x3b, 0xe2, 0xcb, 0x08, 0xcb, 0x09, 0xe3, 0xa1, 0x0b, 0x4c, 0x0a, 0x5f, 0xae, 0x95, 0xc2, 0x4f, - 0x73, 0xa4, 0x13, 0x0b, 0x64, 0xf9, 0x1b, 0xe2, 0xb6, 0xe9, 0xc2, 0x52, 0xc0, 0x5f, 0x81, 0x9b, - 0xd0, 0x9c, 0xbf, 0x40, 0x2b, 0xdb, 0xb8, 0x63, 0x86, 0x65, 0x3d, 0x05, 0xe6, 0x1b, 0xa7, 0x63, - 0x4f, 0xb0, 0xc2, 0x67, 0x4c, 0x16, 0xbd, 0xac, 0x5b, 0x8a, 0x65, 0x27, 0x09, 0xff, 0x70, 0x40, - 0x33, 0xc2, 0x52, 0xf9, 0x2a, 0xc5, 0x5c, 0xc6, 0x4c, 0x4a, 0x26, 0xb8, 0x3f, 0x8e, 0x04, 0x79, - 0xe9, 0xe7, 0xa2, 0xb9, 0xbb, 0x26, 0x87, 0x6f, 0xd7, 0xca, 0xe1, 0x0c, 0x4b, 0x75, 0xb9, 0x80, - 0xd4, 0xd3, 0x40, 0x79, 0x6b, 0x0a, 0x29, 0xa2, 0xbb, 0x5d, 0x60, 0x1d, 0x54, 0x92, 0x94, 0xf6, - 0xfb, 0x23, 0x77, 0xcf, 0xac, 0xad, 0x3d, 0xc1, 0x1f, 0x40, 0xb5, 0x98, 0x7d, 0xf7, 0xa1, 0x49, - 0xa7, 0x73, 0xdf, 0xdd, 0x73, 0x6e, 0x7d, 0x07, 0xfc, 0x85, 0xb0, 0xb4, 0x65, 0x7c, 0xfb, 0x39, - 0xa8, 0xaf, 0x9e, 0x15, 0xcd, 0x6e, 0x4b, 0xd6, 0xf7, 0xdb, 0xf6, 0xd0, 0x9e, 0x60, 0x07, 0xec, - 0xdf, 0x1a, 0xcd, 0x4d, 0xe3, 0xf1, 0x30, 0x5b, 0x9a, 0xa7, 0xf6, 0x33, 0x70, 0xb0, 0x62, 0x08, - 0xe0, 0x37, 0xa0, 0x91, 0x15, 0xfb, 0xb0, 0x70, 0x1f, 0xe0, 0x20, 0x48, 0xa9, 0xcc, 0x6f, 0xd3, - 0xda, 0xf0, 0xbd, 0xd2, 0xa5, 0x5c, 0xef, 0xef, 0x72, 0x87, 0xf6, 0x17, 0xa0, 0x71, 0x76, 0xbf, - 0x6a, 0x0b, 0x79, 0x6f, 0x15, 0x79, 0xb7, 0x15, 0x78, 0x7c, 0x6b, 0xb5, 0xe1, 0x13, 0xf0, 0x20, - 0x93, 0x64, 0x10, 0xd8, 0x1a, 0xf3, 0x03, 0x1c, 0x80, 0xbd, 0x7c, 0xd9, 0xd5, 0x95, 0xaf, 0x53, - 0x36, 0xf5, 0xed, 0x1c, 0x1f, 0xa2, 0xfc, 0x05, 0x41, 0xc5, 0x0b, 0x82, 0x2e, 0x8b, 0x17, 0xa4, - 0x57, 0xd5, 0xba, 0xbe, 0xfa, 0xe7, 0xc8, 0x19, 0xee, 0x16, 0xa1, 0xda, 0xd8, 0x1e, 0x83, 0xfa, - 0xea, 0x49, 0x84, 0xa7, 0x60, 0x3b, 0x62, 0x52, 0x67, 0xb9, 0x95, 0xdf, 0x80, 0xeb, 0xbc, 0x1e, - 0x05, 0x82, 0xed, 0xa3, 0x41, 0xe8, 0xfd, 0xfc, 0xfa, 0xba, 0xe9, 0xbc, 0xb9, 0x6e, 0x3a, 0xff, - 0x5e, 0x37, 0x9d, 0x57, 0x37, 0xcd, 0x8d, 0x37, 0x37, 0xcd, 0x8d, 0xbf, 0x6e, 0x9a, 0x1b, 0xcf, - 0xbf, 0x0e, 0x99, 0x9a, 0x4c, 0xc7, 0x88, 0x88, 0xd8, 0x23, 0x42, 0xc6, 0x42, 0x7a, 0x73, 0x9a, - 0x4f, 0xcb, 0xb7, 0x32, 0x7b, 0xea, 0xfd, 0xb2, 0xfc, 0x0f, 0xc0, 0xbc, 0x7c, 0xe3, 0x8a, 0x29, - 0xf4, 0xf3, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x67, 0x80, 0x40, 0x32, 0x08, 0x00, 0x00, + // 904 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcf, 0x6f, 0x23, 0x35, + 0x14, 0xee, 0xb4, 0xd9, 0x90, 0xb8, 0x3f, 0xb6, 0xeb, 0x2e, 0xd1, 0xd0, 0x88, 0x34, 0x0a, 0x42, + 0x8a, 0xf8, 0xe1, 0x21, 0x45, 0xac, 0x90, 0x10, 0x08, 0xd2, 0x4a, 0x34, 0xab, 0x45, 0x54, 0x69, + 0xb7, 0x48, 0x7b, 0x19, 0x39, 0x1e, 0xef, 0xc4, 0xda, 0x19, 0x3b, 0x1a, 0x7b, 0x26, 0x54, 0x88, + 0x0b, 0x57, 0x2e, 0xfb, 0x37, 0x71, 0xda, 0xe3, 0x1e, 0x39, 0x01, 0x6a, 0xff, 0x11, 0x64, 0x8f, + 0x67, 0x92, 0xb4, 0x69, 0x37, 0xb7, 0xf1, 0xbc, 0xf7, 0xbe, 0xef, 0xbd, 0xef, 0x3d, 0xfb, 0x81, + 0x1e, 0xe3, 0x8a, 0x26, 0x64, 0x8c, 0x19, 0xf7, 0x25, 0x25, 0x69, 0xc2, 0xd4, 0xa5, 0x47, 0x48, + 0xe6, 0x11, 0xc1, 0x65, 0x1a, 0xd3, 0xc4, 0xcb, 0x7a, 0x5e, 0x48, 0x39, 0x95, 0x4c, 0xa2, 0x49, + 0x22, 0x94, 0x80, 0x1f, 0x2d, 0x09, 0x41, 0x84, 0x64, 0xa8, 0x08, 0x41, 0x59, 0x6f, 0xff, 0x8b, + 0xbb, 0x70, 0xb3, 0x9e, 0x27, 0xc7, 0x38, 0xa1, 0x81, 0x5f, 0xba, 0x1b, 0xd8, 0x7d, 0x8f, 0x8d, + 0x88, 0x17, 0xb1, 0x70, 0xac, 0x48, 0xc4, 0x28, 0x57, 0xd2, 0x53, 0x94, 0x07, 0x34, 0x89, 0x19, + 0x57, 0x3a, 0x6a, 0x76, 0xb2, 0x01, 0x8f, 0x43, 0x11, 0x0a, 0xf3, 0xe9, 0xe9, 0x2f, 0xfb, 0xf7, + 0xe3, 0x7b, 0x88, 0xa7, 0x2c, 0xa1, 0xd6, 0xed, 0x20, 0x14, 0x22, 0x8c, 0xa8, 0x67, 0x4e, 0xa3, + 0xf4, 0xa5, 0xa7, 0x58, 0x4c, 0xa5, 0xc2, 0xf1, 0xc4, 0x3a, 0x34, 0xe7, 0xd8, 0xf1, 0x88, 0x30, + 0x4f, 0x5d, 0x4e, 0xa8, 0x95, 0xa0, 0xf3, 0x57, 0x1d, 0x6c, 0xfd, 0x98, 0x8b, 0x72, 0xa6, 0xb0, + 0xa2, 0xf0, 0x04, 0x54, 0x27, 0x38, 0xc1, 0xb1, 0x74, 0x9d, 0xb6, 0xd3, 0xdd, 0x3c, 0xfc, 0x04, + 0xdd, 0x25, 0x52, 0xd6, 0x43, 0x47, 0xb6, 0xf0, 0x53, 0x13, 0xd1, 0xaf, 0xbc, 0xf9, 0xe7, 0x60, + 0x6d, 0x68, 0xe3, 0xe1, 0x67, 0x00, 0x4e, 0x12, 0x91, 0xb1, 0x80, 0x26, 0x7e, 0x2e, 0x84, 0xcf, + 0x02, 0x77, 0xbd, 0xed, 0x74, 0xeb, 0xc3, 0xdd, 0xc2, 0x72, 0x64, 0x0c, 0x83, 0x00, 0x22, 0xb0, + 0x37, 0xf3, 0x1e, 0x63, 0xce, 0x69, 0xa4, 0xdd, 0x37, 0x8c, 0xfb, 0xa3, 0xd2, 0x3d, 0xb7, 0x0c, + 0x02, 0xd8, 0x04, 0x75, 0x4e, 0xa7, 0xbe, 0xc9, 0xcb, 0xad, 0xb4, 0x9d, 0x6e, 0x6d, 0x58, 0xe3, + 0x74, 0x7a, 0xa4, 0xcf, 0x90, 0x80, 0xf7, 0x6f, 0x52, 0x4b, 0x5d, 0x9d, 0xfb, 0xc0, 0xd4, 0xf4, + 0x29, 0x62, 0x23, 0x82, 0xe6, 0x3b, 0x84, 0xe6, 0x7a, 0xa2, 0xeb, 0x32, 0x7f, 0x8d, 0x20, 0xfd, + 0x75, 0xd7, 0x19, 0xee, 0x2d, 0xa6, 0x9b, 0x2b, 0x15, 0x01, 0x77, 0x46, 0x22, 0xb8, 0xa4, 0x5c, + 0xa6, 0xd2, 0xf2, 0x54, 0x0d, 0x0f, 0x7a, 0x27, 0x4f, 0x11, 0x36, 0xa3, 0x6a, 0x94, 0x54, 0x0b, + 0x36, 0x18, 0x82, 0xdd, 0x18, 0xab, 0x34, 0x61, 0x3c, 0xf4, 0x27, 0x98, 0xbc, 0xa2, 0x4a, 0xba, + 0xef, 0xb5, 0x37, 0xba, 0x9b, 0x87, 0x4f, 0xd0, 0x0a, 0x63, 0x8c, 0x7e, 0xb2, 0xc1, 0x17, 0x67, + 0x47, 0xa7, 0x26, 0xdc, 0x76, 0xeb, 0x61, 0x81, 0x9a, 0xff, 0x95, 0xf0, 0x14, 0x3c, 0x64, 0x9c, + 0x29, 0x86, 0x23, 0x3f, 0xc3, 0x91, 0x2f, 0xa9, 0x72, 0x6b, 0x86, 0xa7, 0x3d, 0x9f, 0xbc, 0x1e, + 0x24, 0x74, 0x81, 0x23, 0x16, 0x60, 0x25, 0x92, 0xe7, 0x93, 0x40, 0xe7, 0x5f, 0xd5, 0x88, 0xae, + 0x33, 0xdc, 0xb6, 0x00, 0x17, 0x38, 0x3a, 0xa3, 0x0a, 0xfe, 0x0e, 0xf6, 0xc7, 0x54, 0x8b, 0xe0, + 0x2b, 0xa1, 0x31, 0x25, 0x55, 0x7e, 0x6a, 0x22, 0x74, 0x87, 0xeb, 0x06, 0xfc, 0x9b, 0x95, 0x8a, + 0x38, 0x31, 0x30, 0xe7, 0xe2, 0xc2, 0x80, 0xe4, 0xac, 0x83, 0x63, 0x5b, 0x49, 0x63, 0xbc, 0xcc, + 0x1a, 0xc0, 0x3f, 0x1c, 0xf0, 0xa1, 0x48, 0x95, 0x54, 0x98, 0x07, 0x5a, 0xbd, 0x40, 0x4c, 0xb9, + 0xbe, 0x23, 0xbe, 0x8c, 0xb0, 0x1c, 0x33, 0x1e, 0xba, 0xc0, 0xa4, 0xf0, 0xf5, 0x4a, 0x29, 0xfc, + 0x3c, 0x43, 0x3a, 0xb6, 0x40, 0x96, 0xbf, 0x29, 0x6e, 0x9b, 0xce, 0x2c, 0x05, 0xfc, 0x0d, 0xb8, + 0x13, 0x9a, 0xf3, 0x17, 0x68, 0x65, 0x1b, 0x37, 0xcd, 0xb0, 0xac, 0xa6, 0xc0, 0xec, 0xc6, 0xe9, + 0xd8, 0x63, 0xac, 0xf0, 0x33, 0x26, 0x8b, 0x5e, 0x36, 0x2c, 0xc5, 0xa2, 0x93, 0x84, 0x7f, 0x3a, + 0xa0, 0x15, 0x61, 0xa9, 0x7c, 0x95, 0x60, 0x2e, 0x63, 0x26, 0x25, 0x13, 0xdc, 0x1f, 0x45, 0x82, + 0xbc, 0xf2, 0x73, 0xd1, 0xdc, 0x2d, 0x93, 0xc3, 0xf7, 0x2b, 0xe5, 0xf0, 0x0c, 0x4b, 0x75, 0x3e, + 0x87, 0xd4, 0xd7, 0x40, 0x79, 0x6b, 0x0a, 0x29, 0xa2, 0xbb, 0x5d, 0xe0, 0x53, 0x50, 0x2b, 0x66, + 0xdc, 0xdd, 0x31, 0xb4, 0xdd, 0xfb, 0xde, 0x98, 0x53, 0xeb, 0x3b, 0xe0, 0x2f, 0x85, 0x85, 0x2f, + 0xe3, 0x9f, 0x56, 0x6a, 0xdb, 0xbb, 0x3b, 0x9d, 0x17, 0xa0, 0xb1, 0x7c, 0x32, 0x60, 0x03, 0x54, + 0x6d, 0x81, 0xfa, 0x35, 0xab, 0x0c, 0xed, 0x09, 0x76, 0xc1, 0xee, 0xad, 0x41, 0x5c, 0x37, 0x1e, + 0x3b, 0xd9, 0xc2, 0xf4, 0x74, 0x9e, 0x83, 0xbd, 0x25, 0x2d, 0x87, 0xdf, 0x81, 0x66, 0x56, 0x4c, + 0xff, 0xdc, 0xed, 0xc7, 0x41, 0x90, 0x50, 0x99, 0xbf, 0x9d, 0xf5, 0xe1, 0x07, 0xa5, 0x4b, 0x79, + 0x99, 0x7f, 0xc8, 0x1d, 0x3a, 0x5f, 0x81, 0xe6, 0x3d, 0x32, 0xde, 0xc8, 0x7b, 0xa3, 0xc8, 0xbb, + 0xa3, 0xc0, 0xa3, 0x5b, 0x17, 0x19, 0x3e, 0x06, 0x0f, 0x32, 0x49, 0x06, 0x81, 0xad, 0x31, 0x3f, + 0xc0, 0x01, 0xd8, 0xce, 0xaf, 0xb6, 0xba, 0xf4, 0x75, 0xca, 0xa6, 0xbe, 0xcd, 0xc3, 0x7d, 0x94, + 0xef, 0x0b, 0x54, 0xec, 0x0b, 0x74, 0x5e, 0xec, 0x8b, 0x7e, 0x4d, 0xab, 0xfb, 0xfa, 0xdf, 0x03, + 0x67, 0xb8, 0x55, 0x84, 0x6a, 0x63, 0x67, 0x04, 0x1a, 0xcb, 0xe7, 0x0e, 0x9e, 0x80, 0x4a, 0xc4, + 0xa4, 0xce, 0x72, 0x23, 0x7f, 0xef, 0x56, 0xd9, 0x15, 0x05, 0x82, 0xed, 0xa6, 0x41, 0xe8, 0xff, + 0xf2, 0xe6, 0xaa, 0xe5, 0xbc, 0xbd, 0x6a, 0x39, 0xff, 0x5d, 0xb5, 0x9c, 0xd7, 0xd7, 0xad, 0xb5, + 0xb7, 0xd7, 0xad, 0xb5, 0xbf, 0xaf, 0x5b, 0x6b, 0x2f, 0xbe, 0x0d, 0x99, 0x1a, 0xa7, 0x23, 0x44, + 0x44, 0xec, 0x11, 0x21, 0x63, 0x21, 0xbd, 0x19, 0xcd, 0xe7, 0xe5, 0x66, 0xcc, 0x9e, 0x78, 0xbf, + 0x2e, 0xee, 0x7b, 0xb3, 0xe7, 0x46, 0x55, 0x53, 0xe8, 0x97, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x07, 0xc0, 0xce, 0x30, 0x20, 0x08, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -553,16 +544,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x72 - if m.PreCCV { - i-- - if m.PreCCV { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x68 - } { size, err := m.LastTransmissionBlockHeight.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -930,9 +911,6 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) l = m.LastTransmissionBlockHeight.Size() n += 1 + l + sovGenesis(uint64(l)) - if m.PreCCV { - n += 2 - } l = m.Provider.Size() n += 1 + l + sovGenesis(uint64(l)) return n @@ -1433,26 +1411,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 13: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.PreCCV = bool(v != 0) case 14: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Provider", wireType) diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index b77ee85f1a..cc04a9f487 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -94,13 +94,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, - PreCCV: false, }, true, }, @@ -115,13 +115,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, - PreCCV: false, }, true, }, @@ -136,13 +136,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: []types.MaturingVSCPacket{{}}, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, - PreCCV: false, }, true, }, @@ -157,13 +157,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{Height: 1}, - PreCCV: false, }, true, }, @@ -178,13 +178,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{List: []ccv.ConsumerPacketData{{}}}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, - PreCCV: false, }, true, }, @@ -369,13 +369,13 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { ClientState: cs, ConsensusState: nil, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, - PreCCV: false, }, true, }, @@ -390,13 +390,13 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { ClientState: nil, ConsensusState: consensusState, InitialValSet: valUpdates, + PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, - PreCCV: false, }, true, }, diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index b9dd99caf0..abdf3d82bf 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -217,7 +217,9 @@ func (m *ConsumerParams) GetConsumerId() string { type ConsumerGenesisState struct { Params ConsumerParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` Provider ProviderInfo `protobuf:"bytes,2,opt,name=provider,proto3" json:"provider"` - // true for new chain, false for chain restart. + // True for new chain, false for chain restart. + // This is needed and always set to true; otherwise, new_chain in the consumer + // genesis state will default to false NewChain bool `protobuf:"varint,3,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` } @@ -278,12 +280,21 @@ func (m *ConsumerGenesisState) GetNewChain() bool { // ProviderInfo defines all information a consumer needs from a provider // Shared data type between provider and consumer type ProviderInfo struct { - // ProviderClientState filled in on new chain, nil on restart. + // The client state for the provider client filled in on new chain, nil on restart. + // If connection_id != "", then client_state is ignored. ClientState *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"` - // ProviderConsensusState filled in on new chain, nil on restart. + // The consensus state for the provider client filled in on new chain, nil on restart. + // If connection_id != "", then consensus_state is ignored. ConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty"` // InitialValset filled in on new chain and on restart. InitialValSet []types.ValidatorUpdate `protobuf:"bytes,3,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` + // The ID of the connection end on the consumer chain on top of which the + // CCV channel will be established. If connection_id == "", a new client of + // the provider chain and a new connection on top of this client are created. + // The new client is initialized using client_state and consensus_state. + ConnectionId string `protobuf:"bytes,4,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + // Flag indicating whether the consumer CCV module starts in pre-CCV state + PreCCV bool `protobuf:"varint,5,opt,name=preCCV,proto3" json:"preCCV,omitempty"` } func (m *ProviderInfo) Reset() { *m = ProviderInfo{} } @@ -340,6 +351,20 @@ func (m *ProviderInfo) GetInitialValSet() []types.ValidatorUpdate { return nil } +func (m *ProviderInfo) GetConnectionId() string { + if m != nil { + return m.ConnectionId + } + return "" +} + +func (m *ProviderInfo) GetPreCCV() bool { + if m != nil { + return m.PreCCV + } + return false +} + func init() { proto.RegisterType((*ConsumerParams)(nil), "interchain_security.ccv.v1.ConsumerParams") proto.RegisterType((*ConsumerGenesisState)(nil), "interchain_security.ccv.v1.ConsumerGenesisState") @@ -351,60 +376,61 @@ func init() { } var fileDescriptor_d0a8be0efc64dfbc = []byte{ - // 833 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcf, 0x73, 0xdc, 0x34, - 0x14, 0x8e, 0xb3, 0x25, 0xd9, 0x68, 0xf3, 0xa3, 0x88, 0x50, 0x4c, 0x3a, 0xb3, 0xd9, 0x06, 0x0e, - 0x3b, 0x30, 0xb5, 0x49, 0xe8, 0xc0, 0x0c, 0x37, 0x92, 0x50, 0xda, 0x1e, 0x92, 0xad, 0x13, 0xca, - 0x0c, 0x1c, 0x34, 0xb2, 0xf4, 0x76, 0xad, 0xc1, 0x96, 0x3c, 0x92, 0xec, 0x90, 0x3b, 0x33, 0x5c, - 0x39, 0xf2, 0x27, 0x95, 0x5b, 0x8f, 0x9c, 0x80, 0x49, 0xfe, 0x11, 0xc6, 0xb2, 0xbd, 0xf1, 0x32, - 0x04, 0xda, 0x9b, 0x9f, 0xf4, 0x7d, 0x9f, 0xf5, 0xbd, 0xa7, 0xf7, 0x84, 0x3e, 0x11, 0xd2, 0x82, - 0x66, 0x09, 0x15, 0x92, 0x18, 0x60, 0x85, 0x16, 0xf6, 0x32, 0x64, 0xac, 0x0c, 0xcb, 0xfd, 0xd0, - 0x24, 0x54, 0x03, 0x27, 0x4c, 0x49, 0x53, 0x64, 0xa0, 0x83, 0x5c, 0x2b, 0xab, 0xf0, 0xce, 0xbf, - 0x30, 0x02, 0xc6, 0xca, 0xa0, 0xdc, 0xdf, 0xb9, 0x6f, 0x41, 0x72, 0xd0, 0x99, 0x90, 0x36, 0xa4, - 0x31, 0x13, 0xa1, 0xbd, 0xcc, 0xc1, 0xd4, 0xc4, 0x9d, 0x50, 0xc4, 0x2c, 0x4c, 0xc5, 0x2c, 0xb1, - 0x2c, 0x15, 0x20, 0xad, 0x09, 0x3b, 0xe8, 0x72, 0xbf, 0x13, 0x35, 0x84, 0xe1, 0x4c, 0xa9, 0x59, - 0x0a, 0xa1, 0x8b, 0xe2, 0x62, 0x1a, 0xf2, 0x42, 0x53, 0x2b, 0x94, 0x6c, 0xf6, 0xb7, 0x67, 0x6a, - 0xa6, 0xdc, 0x67, 0x58, 0x7d, 0xd5, 0xab, 0x7b, 0x3f, 0xad, 0xa2, 0xcd, 0xa3, 0xe6, 0xc8, 0x13, - 0xaa, 0x69, 0x66, 0xb0, 0x8f, 0x56, 0x41, 0xd2, 0x38, 0x05, 0xee, 0x7b, 0x23, 0x6f, 0xdc, 0x8f, - 0xda, 0x10, 0x9f, 0xa2, 0x0f, 0xe3, 0x54, 0xb1, 0x1f, 0x0c, 0xc9, 0x41, 0x13, 0x2e, 0x8c, 0xd5, - 0x22, 0x2e, 0xaa, 0x7f, 0x10, 0xab, 0xa9, 0x34, 0x99, 0x30, 0x46, 0x28, 0xe9, 0x2f, 0x8f, 0xbc, - 0x71, 0x2f, 0x7a, 0x50, 0x63, 0x27, 0xa0, 0x8f, 0x3b, 0xc8, 0xf3, 0x0e, 0x10, 0x3f, 0x43, 0x0f, - 0x6e, 0x55, 0x21, 0x2c, 0xa1, 0x52, 0x42, 0xea, 0xf7, 0x46, 0xde, 0x78, 0x2d, 0xda, 0xe5, 0xb7, - 0x88, 0x1c, 0xd5, 0x30, 0xfc, 0x05, 0xda, 0xc9, 0xb5, 0x2a, 0x05, 0x07, 0x4d, 0xa6, 0x00, 0x24, - 0x57, 0x2a, 0x25, 0x94, 0x73, 0x4d, 0x8c, 0xd5, 0xfe, 0x1d, 0x27, 0x72, 0xaf, 0x45, 0x3c, 0x06, - 0x98, 0x28, 0x95, 0x7e, 0xc9, 0xb9, 0x3e, 0xb3, 0x1a, 0x3f, 0x47, 0x98, 0xb1, 0x92, 0x58, 0x91, - 0x81, 0x2a, 0x6c, 0xe5, 0x4e, 0x28, 0xee, 0xbf, 0x35, 0xf2, 0xc6, 0x83, 0x83, 0xf7, 0x83, 0x3a, - 0xb1, 0x41, 0x9b, 0xd8, 0xe0, 0xb8, 0x49, 0xec, 0x61, 0xff, 0xe5, 0x1f, 0xbb, 0x4b, 0xbf, 0xfe, - 0xb9, 0xeb, 0x45, 0x77, 0x19, 0x2b, 0xcf, 0x6b, 0xf6, 0xc4, 0x91, 0xf1, 0xf7, 0xe8, 0x3d, 0xe7, - 0x66, 0x0a, 0xfa, 0x9f, 0xba, 0x2b, 0xaf, 0xaf, 0xfb, 0x6e, 0xab, 0xb1, 0x28, 0xfe, 0x04, 0x8d, - 0xda, 0x7b, 0x46, 0x34, 0x2c, 0xa4, 0x70, 0xaa, 0x29, 0xab, 0x3e, 0xfc, 0x55, 0xe7, 0x78, 0xd8, - 0xe2, 0xa2, 0x05, 0xd8, 0xe3, 0x06, 0x85, 0x1f, 0x22, 0x9c, 0x08, 0x63, 0x95, 0x16, 0x8c, 0xa6, - 0x04, 0xa4, 0xd5, 0x02, 0x8c, 0xdf, 0x77, 0x05, 0x7c, 0xfb, 0x66, 0xe7, 0xab, 0x7a, 0x03, 0x9f, - 0xa0, 0xbb, 0x85, 0x8c, 0x95, 0xe4, 0x42, 0xce, 0x5a, 0x3b, 0x6b, 0xaf, 0x6f, 0x67, 0x6b, 0x4e, - 0x6e, 0x8c, 0x7c, 0x8e, 0xee, 0x19, 0x35, 0xb5, 0x44, 0xe5, 0x96, 0x54, 0x19, 0xb2, 0x89, 0x06, - 0x93, 0xa8, 0x94, 0xfb, 0xa8, 0x3a, 0xfe, 0xe1, 0xb2, 0xef, 0x45, 0xef, 0x54, 0x88, 0xd3, 0xdc, - 0x9e, 0x16, 0xf6, 0xbc, 0xdd, 0xc6, 0x1f, 0xa0, 0x0d, 0x0d, 0x17, 0x54, 0x73, 0xc2, 0x41, 0xaa, - 0xcc, 0xf8, 0x83, 0x51, 0x6f, 0xbc, 0x16, 0xad, 0xd7, 0x8b, 0xc7, 0x6e, 0x0d, 0x3f, 0x42, 0xf3, - 0x82, 0x93, 0x45, 0xf4, 0xba, 0x43, 0x6f, 0xb7, 0xbb, 0x51, 0x97, 0xf5, 0x1c, 0x61, 0x0d, 0x56, - 0x5f, 0x12, 0x0e, 0x29, 0xbd, 0x6c, 0x5d, 0x6e, 0xbc, 0xc1, 0x65, 0x70, 0xf4, 0xe3, 0x8a, 0xdd, - 0xd8, 0xdc, 0x45, 0x83, 0x79, 0xbd, 0x04, 0xf7, 0x37, 0x5d, 0x69, 0x50, 0xbb, 0xf4, 0x94, 0xef, - 0xfd, 0xe6, 0xa1, 0xed, 0xb6, 0x0d, 0xbf, 0x06, 0x09, 0x46, 0x98, 0x33, 0x4b, 0x2d, 0xe0, 0x27, - 0x68, 0x25, 0x77, 0x6d, 0xe9, 0x7a, 0x71, 0x70, 0xf0, 0x51, 0x70, 0xfb, 0x40, 0x09, 0x16, 0x1b, - 0xf9, 0xf0, 0x4e, 0x75, 0xa2, 0xa8, 0xe1, 0xe3, 0x67, 0xa8, 0xdf, 0xda, 0x75, 0x0d, 0x3a, 0x38, - 0x18, 0xff, 0x97, 0xd6, 0xa4, 0xc1, 0x3e, 0x95, 0x53, 0xd5, 0x28, 0xcd, 0xf9, 0xf8, 0x3e, 0x5a, - 0x93, 0x70, 0x41, 0x1c, 0xd3, 0xf5, 0x67, 0x3f, 0xea, 0x4b, 0xb8, 0x38, 0xaa, 0xe2, 0xbd, 0x9f, - 0x97, 0xd1, 0x7a, 0x97, 0x8d, 0x4f, 0xd0, 0x7a, 0x3d, 0xc3, 0x88, 0xa9, 0x3c, 0x35, 0x4e, 0x3e, - 0x0e, 0x44, 0xcc, 0x82, 0xee, 0x84, 0x0b, 0x3a, 0x33, 0xad, 0x72, 0xe3, 0x56, 0x5d, 0x1a, 0xa2, - 0x01, 0xbb, 0x09, 0xf0, 0xb7, 0x68, 0xab, 0x4a, 0x1d, 0x48, 0x53, 0x98, 0x46, 0xb2, 0x36, 0x14, - 0xfc, 0xaf, 0x64, 0x4b, 0xab, 0x55, 0x37, 0xd9, 0x42, 0x8c, 0x4f, 0xd0, 0x96, 0x90, 0xc2, 0x0a, - 0x9a, 0x92, 0x92, 0xa6, 0xc4, 0x80, 0xf5, 0x7b, 0xa3, 0xde, 0x78, 0x70, 0x30, 0xea, 0xea, 0x54, - 0xa3, 0x3a, 0x78, 0x41, 0x53, 0xc1, 0xa9, 0x55, 0xfa, 0x9b, 0x9c, 0x53, 0x0b, 0x4d, 0x86, 0x36, - 0x1a, 0xfa, 0x0b, 0x9a, 0x9e, 0x81, 0x3d, 0x3c, 0x79, 0x79, 0x35, 0xf4, 0x5e, 0x5d, 0x0d, 0xbd, - 0xbf, 0xae, 0x86, 0xde, 0x2f, 0xd7, 0xc3, 0xa5, 0x57, 0xd7, 0xc3, 0xa5, 0xdf, 0xaf, 0x87, 0x4b, - 0xdf, 0x3d, 0x9a, 0x09, 0x9b, 0x14, 0x71, 0xc0, 0x54, 0x16, 0x32, 0x65, 0x32, 0x65, 0xc2, 0x9b, - 0x5a, 0x3c, 0x9c, 0x3f, 0x2d, 0xe5, 0x67, 0xe1, 0x8f, 0xee, 0x7d, 0x71, 0x2f, 0x43, 0xbc, 0xe2, - 0x6e, 0xdd, 0xa7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xf0, 0xde, 0x5e, 0x87, 0x06, 0x00, - 0x00, + // 864 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x53, 0xe4, 0x44, + 0x14, 0x26, 0xcc, 0x0a, 0x43, 0xcf, 0x00, 0x6b, 0x8b, 0x18, 0xd9, 0xaa, 0x61, 0x16, 0x3d, 0x4c, + 0x69, 0x6d, 0x22, 0xb8, 0xa5, 0x55, 0xde, 0x64, 0x70, 0x5d, 0xf6, 0x00, 0xb3, 0x01, 0xb1, 0x4a, + 0x0f, 0x5d, 0x9d, 0xee, 0x37, 0x33, 0x5d, 0x66, 0xba, 0x53, 0xdd, 0x9d, 0x20, 0x77, 0x7f, 0x80, + 0x47, 0x7f, 0x90, 0x87, 0xf5, 0xb6, 0x47, 0x4f, 0x6a, 0xc1, 0x1f, 0xb1, 0xd2, 0x49, 0x86, 0x8c, + 0x25, 0xca, 0xde, 0xf2, 0x5e, 0x7f, 0xdf, 0x97, 0x7c, 0xef, 0xf5, 0x7b, 0x41, 0x9f, 0x08, 0x69, + 0x41, 0xb3, 0x29, 0x15, 0x92, 0x18, 0x60, 0x99, 0x16, 0xf6, 0x2a, 0x64, 0x2c, 0x0f, 0xf3, 0xfd, + 0xd0, 0x4c, 0xa9, 0x06, 0x4e, 0x98, 0x92, 0x26, 0x9b, 0x81, 0x0e, 0x52, 0xad, 0xac, 0xc2, 0x3b, + 0xff, 0xc2, 0x08, 0x18, 0xcb, 0x83, 0x7c, 0x7f, 0xe7, 0x91, 0x05, 0xc9, 0x41, 0xcf, 0x84, 0xb4, + 0x21, 0x8d, 0x99, 0x08, 0xed, 0x55, 0x0a, 0xa6, 0x24, 0xee, 0x84, 0x22, 0x66, 0x61, 0x22, 0x26, + 0x53, 0xcb, 0x12, 0x01, 0xd2, 0x9a, 0xb0, 0x81, 0xce, 0xf7, 0x1b, 0x51, 0x45, 0xe8, 0x4d, 0x94, + 0x9a, 0x24, 0x10, 0xba, 0x28, 0xce, 0xc6, 0x21, 0xcf, 0x34, 0xb5, 0x42, 0xc9, 0xea, 0x7c, 0x6b, + 0xa2, 0x26, 0xca, 0x3d, 0x86, 0xc5, 0x53, 0x99, 0xdd, 0xfb, 0x69, 0x15, 0x6d, 0x0c, 0xab, 0x4f, + 0x1e, 0x51, 0x4d, 0x67, 0x06, 0xfb, 0x68, 0x15, 0x24, 0x8d, 0x13, 0xe0, 0xbe, 0xd7, 0xf7, 0x06, + 0xed, 0xa8, 0x0e, 0xf1, 0x29, 0xfa, 0x30, 0x4e, 0x14, 0xfb, 0xc1, 0x90, 0x14, 0x34, 0xe1, 0xc2, + 0x58, 0x2d, 0xe2, 0xac, 0x78, 0x07, 0xb1, 0x9a, 0x4a, 0x33, 0x13, 0xc6, 0x08, 0x25, 0xfd, 0xe5, + 0xbe, 0x37, 0x68, 0x45, 0x8f, 0x4b, 0xec, 0x08, 0xf4, 0x51, 0x03, 0x79, 0xde, 0x00, 0xe2, 0x17, + 0xe8, 0xf1, 0x9d, 0x2a, 0x84, 0x4d, 0xa9, 0x94, 0x90, 0xf8, 0xad, 0xbe, 0x37, 0x58, 0x8b, 0x76, + 0xf9, 0x1d, 0x22, 0xc3, 0x12, 0x86, 0xbf, 0x40, 0x3b, 0xa9, 0x56, 0xb9, 0xe0, 0xa0, 0xc9, 0x18, + 0x80, 0xa4, 0x4a, 0x25, 0x84, 0x72, 0xae, 0x89, 0xb1, 0xda, 0x7f, 0xe0, 0x44, 0xb6, 0x6b, 0xc4, + 0x33, 0x80, 0x91, 0x52, 0xc9, 0x97, 0x9c, 0xeb, 0x33, 0xab, 0xf1, 0x4b, 0x84, 0x19, 0xcb, 0x89, + 0x15, 0x33, 0x50, 0x99, 0x2d, 0xdc, 0x09, 0xc5, 0xfd, 0xb7, 0xfa, 0xde, 0xa0, 0x73, 0xf0, 0x7e, + 0x50, 0x16, 0x36, 0xa8, 0x0b, 0x1b, 0x1c, 0x55, 0x85, 0x3d, 0x6c, 0xbf, 0xfa, 0x63, 0x77, 0xe9, + 0x97, 0x3f, 0x77, 0xbd, 0xe8, 0x21, 0x63, 0xf9, 0x79, 0xc9, 0x1e, 0x39, 0x32, 0xfe, 0x1e, 0xbd, + 0xe7, 0xdc, 0x8c, 0x41, 0xff, 0x53, 0x77, 0xe5, 0xfe, 0xba, 0xef, 0xd6, 0x1a, 0x8b, 0xe2, 0xcf, + 0x51, 0xbf, 0xbe, 0x67, 0x44, 0xc3, 0x42, 0x09, 0xc7, 0x9a, 0xb2, 0xe2, 0xc1, 0x5f, 0x75, 0x8e, + 0x7b, 0x35, 0x2e, 0x5a, 0x80, 0x3d, 0xab, 0x50, 0xf8, 0x09, 0xc2, 0x53, 0x61, 0xac, 0xd2, 0x82, + 0xd1, 0x84, 0x80, 0xb4, 0x5a, 0x80, 0xf1, 0xdb, 0xae, 0x81, 0x6f, 0xdf, 0x9e, 0x7c, 0x55, 0x1e, + 0xe0, 0x13, 0xf4, 0x30, 0x93, 0xb1, 0x92, 0x5c, 0xc8, 0x49, 0x6d, 0x67, 0xed, 0xfe, 0x76, 0x36, + 0xe7, 0xe4, 0xca, 0xc8, 0xe7, 0x68, 0xdb, 0xa8, 0xb1, 0x25, 0x2a, 0xb5, 0xa4, 0xa8, 0x90, 0x9d, + 0x6a, 0x30, 0x53, 0x95, 0x70, 0x1f, 0x15, 0x9f, 0x7f, 0xb8, 0xec, 0x7b, 0xd1, 0x3b, 0x05, 0xe2, + 0x34, 0xb5, 0xa7, 0x99, 0x3d, 0xaf, 0x8f, 0xf1, 0x07, 0x68, 0x5d, 0xc3, 0x25, 0xd5, 0x9c, 0x70, + 0x90, 0x6a, 0x66, 0xfc, 0x4e, 0xbf, 0x35, 0x58, 0x8b, 0xba, 0x65, 0xf2, 0xc8, 0xe5, 0xf0, 0x53, + 0x34, 0x6f, 0x38, 0x59, 0x44, 0x77, 0x1d, 0x7a, 0xab, 0x3e, 0x8d, 0x9a, 0xac, 0x97, 0x08, 0x6b, + 0xb0, 0xfa, 0x8a, 0x70, 0x48, 0xe8, 0x55, 0xed, 0x72, 0xfd, 0x0d, 0x2e, 0x83, 0xa3, 0x1f, 0x15, + 0xec, 0xca, 0xe6, 0x2e, 0xea, 0xcc, 0xfb, 0x25, 0xb8, 0xbf, 0xe1, 0x5a, 0x83, 0xea, 0xd4, 0x31, + 0xdf, 0xfb, 0xcd, 0x43, 0x5b, 0xf5, 0x18, 0x7e, 0x0d, 0x12, 0x8c, 0x30, 0x67, 0x96, 0x5a, 0xc0, + 0xcf, 0xd1, 0x4a, 0xea, 0xc6, 0xd2, 0xcd, 0x62, 0xe7, 0xe0, 0xa3, 0xe0, 0xee, 0x85, 0x12, 0x2c, + 0x0e, 0xf2, 0xe1, 0x83, 0xe2, 0x8b, 0xa2, 0x8a, 0x8f, 0x5f, 0xa0, 0x76, 0x6d, 0xd7, 0x0d, 0x68, + 0xe7, 0x60, 0xf0, 0x5f, 0x5a, 0xa3, 0x0a, 0x7b, 0x2c, 0xc7, 0xaa, 0x52, 0x9a, 0xf3, 0xf1, 0x23, + 0xb4, 0x26, 0xe1, 0x92, 0x38, 0xa6, 0x9b, 0xcf, 0x76, 0xd4, 0x96, 0x70, 0x39, 0x2c, 0xe2, 0xbd, + 0x5f, 0x97, 0x51, 0xb7, 0xc9, 0xc6, 0x27, 0xa8, 0x5b, 0xee, 0x30, 0x62, 0x0a, 0x4f, 0x95, 0x93, + 0x8f, 0x03, 0x11, 0xb3, 0xa0, 0xb9, 0xe1, 0x82, 0xc6, 0x4e, 0x2b, 0xdc, 0xb8, 0xac, 0x2b, 0x43, + 0xd4, 0x61, 0xb7, 0x01, 0xfe, 0x16, 0x6d, 0x16, 0xa5, 0x03, 0x69, 0x32, 0x53, 0x49, 0x96, 0x86, + 0x82, 0xff, 0x95, 0xac, 0x69, 0xa5, 0xea, 0x06, 0x5b, 0x88, 0xf1, 0x09, 0xda, 0x14, 0x52, 0x58, + 0x41, 0x13, 0x92, 0xd3, 0x84, 0x18, 0xb0, 0x7e, 0xab, 0xdf, 0x1a, 0x74, 0x0e, 0xfa, 0x4d, 0x9d, + 0x62, 0x55, 0x07, 0x17, 0x34, 0x11, 0x9c, 0x5a, 0xa5, 0xbf, 0x49, 0x39, 0xb5, 0x50, 0x55, 0x68, + 0xbd, 0xa2, 0x5f, 0xd0, 0xe4, 0x0c, 0x6c, 0x71, 0x49, 0x99, 0x92, 0x12, 0xdc, 0xa8, 0x15, 0x8d, + 0x2f, 0xb7, 0x50, 0xf7, 0x36, 0x79, 0xcc, 0xf1, 0x36, 0x5a, 0x49, 0x35, 0x0c, 0x87, 0x17, 0x6e, + 0xdf, 0xb4, 0xa3, 0x2a, 0x3a, 0x3c, 0x79, 0x75, 0xdd, 0xf3, 0x5e, 0x5f, 0xf7, 0xbc, 0xbf, 0xae, + 0x7b, 0xde, 0xcf, 0x37, 0xbd, 0xa5, 0xd7, 0x37, 0xbd, 0xa5, 0xdf, 0x6f, 0x7a, 0x4b, 0xdf, 0x3d, + 0x9d, 0x08, 0x3b, 0xcd, 0xe2, 0x80, 0xa9, 0x59, 0xc8, 0x94, 0x99, 0x29, 0x13, 0xde, 0x36, 0xf2, + 0xc9, 0xfc, 0xbf, 0x94, 0x7f, 0x16, 0xfe, 0xe8, 0x7e, 0x4e, 0xee, 0xb7, 0x12, 0xaf, 0xb8, 0x2b, + 0xfb, 0xe9, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x64, 0xc8, 0x7f, 0xef, 0xc4, 0x06, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { @@ -608,6 +634,23 @@ func (m *ProviderInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PreCCV { + i-- + if m.PreCCV { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x22 + } if len(m.InitialValSet) > 0 { for iNdEx := len(m.InitialValSet) - 1; iNdEx >= 0; iNdEx-- { { @@ -754,6 +797,13 @@ func (m *ProviderInfo) Size() (n int) { n += 1 + l + sovSharedConsumer(uint64(l)) } } + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovSharedConsumer(uint64(l)) + } + if m.PreCCV { + n += 2 + } return n } @@ -1498,6 +1548,58 @@ func (m *ProviderInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSharedConsumer + } + 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 ErrInvalidLengthSharedConsumer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSharedConsumer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSharedConsumer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PreCCV = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSharedConsumer(dAtA[iNdEx:]) From 85e9a5357f0dfc92632ac035a3006f31f2159ecf Mon Sep 17 00:00:00 2001 From: mpoke Date: Tue, 5 Nov 2024 09:38:06 +0100 Subject: [PATCH 04/25] move preccv and connId to ConsumerGenesisState --- app/consumer-democracy/app.go | 2 +- .../ccv/consumer/v1/genesis.proto | 10 +- .../ccv/v1/shared_consumer.proto | 14 +- x/ccv/consumer/keeper/genesis.go | 4 +- x/ccv/consumer/types/genesis.pb.go | 217 +++++++++---- x/ccv/consumer/types/genesis_test.go | 14 +- x/ccv/provider/keeper/consumer_lifecycle.go | 67 ++-- x/ccv/provider/types/genesis.go | 4 - x/ccv/provider/types/genesis_test.go | 136 +++----- x/ccv/provider/types/msg.go | 11 +- x/ccv/provider/types/msg_test.go | 43 --- x/ccv/provider/types/params.go | 29 +- x/ccv/types/genesis.go | 40 ++- x/ccv/types/shared_consumer.pb.go | 302 +++++++++--------- x/ccv/types/shared_params.go | 21 ++ x/ccv/types/shared_params_test.go | 48 +++ 16 files changed, 542 insertions(+), 420 deletions(-) diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 08c0ed1d5d..ac65478bfe 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -696,7 +696,7 @@ func New( consumerGenesis := consumertypes.GenesisState{} appCodec.MustUnmarshalJSON(appState[consumertypes.ModuleName], &consumerGenesis) - consumerGenesis.Provider.PreCCV = true + consumerGenesis.PreCCV = true app.ConsumerKeeper.InitGenesis(sdkCtx, &consumerGenesis) app.Logger().Info("start to run module migrations...") diff --git a/proto/interchain_security/ccv/consumer/v1/genesis.proto b/proto/interchain_security/ccv/consumer/v1/genesis.proto index 9007af0f44..ea0f6a6f78 100644 --- a/proto/interchain_security/ccv/consumer/v1/genesis.proto +++ b/proto/interchain_security/ccv/consumer/v1/genesis.proto @@ -20,9 +20,6 @@ import "tendermint/abci/types.proto"; // Note: this type is only used on consumer side and references shared types with // provider message GenesisState { - // Reserve 13th slot for removed preCCV field - reserved 13; - // ConsumerParams is a shared type with provider module interchain_security.ccv.v1.ConsumerParams params = 1 [ (gogoproto.nullable) = false ]; @@ -53,8 +50,15 @@ message GenesisState { // LastTransmissionBlockHeight nil on new chain, filled in on restart. LastTransmissionBlockHeight last_transmission_block_height = 12 [ (gogoproto.nullable) = false ]; + // Flag indicating whether the consumer CCV module starts in pre-CCV state + bool preCCV = 13; interchain_security.ccv.v1.ProviderInfo provider = 14 [ (gogoproto.nullable) = false ]; + // The ID of the connection end on the consumer chain on top of which the + // CCV channel will be established. If connection_id == "", a new client of + // the provider chain and a new connection on top of this client are created. + // The new client is initialized using provider.client_state and provider.consensus_state. + string connection_id = 15; } // HeightValsetUpdateID represents a mapping internal to the consumer CCV module diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index 44d5d9dc5e..2a25a46858 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -91,6 +91,13 @@ message ConsumerGenesisState { // This is needed and always set to true; otherwise, new_chain in the consumer // genesis state will default to false bool new_chain = 3; + // Flag indicating whether the consumer CCV module starts in pre-CCV state + bool preCCV = 4; + // The ID of the connection end on the consumer chain on top of which the + // CCV channel will be established. If connection_id == "", a new client of + // the provider chain and a new connection on top of this client are created. + // The new client is initialized using client_state and consensus_state. + string connection_id = 5; } // ProviderInfo defines all information a consumer needs from a provider @@ -105,11 +112,4 @@ message ProviderInfo { // InitialValset filled in on new chain and on restart. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 [ (gogoproto.nullable) = false ]; - // The ID of the connection end on the consumer chain on top of which the - // CCV channel will be established. If connection_id == "", a new client of - // the provider chain and a new connection on top of this client are created. - // The new client is initialized using client_state and consensus_state. - string connection_id = 4; - // Flag indicating whether the consumer CCV module starts in pre-CCV state - bool preCCV = 5; } diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index b62d6a62fe..e45a5fa892 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -24,7 +24,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V // Once the provider validator set starts validating blocks, the consumer CCV module // will take over proof of stake capabilities, but the standalone staking keeper will // stick around for slashing/jailing purposes. - if state.Provider.PreCCV { + if state.PreCCV { k.SetPreCCVTrue(ctx) k.MarkAsPrevStandaloneChain(ctx) k.SetInitialValSet(ctx, state.Provider.InitialValSet) @@ -106,7 +106,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V k.SetProviderClientID(ctx, state.ProviderClientId) } - if state.Provider.PreCCV { + if state.PreCCV { return []abci.ValidatorUpdate{} } diff --git a/x/ccv/consumer/types/genesis.pb.go b/x/ccv/consumer/types/genesis.pb.go index 88869fa300..3214b51c9e 100644 --- a/x/ccv/consumer/types/genesis.pb.go +++ b/x/ccv/consumer/types/genesis.pb.go @@ -59,7 +59,14 @@ type GenesisState struct { PendingConsumerPackets ConsumerPacketDataList `protobuf:"bytes,11,opt,name=pending_consumer_packets,json=pendingConsumerPackets,proto3" json:"pending_consumer_packets"` // LastTransmissionBlockHeight nil on new chain, filled in on restart. LastTransmissionBlockHeight LastTransmissionBlockHeight `protobuf:"bytes,12,opt,name=last_transmission_block_height,json=lastTransmissionBlockHeight,proto3" json:"last_transmission_block_height"` - Provider types.ProviderInfo `protobuf:"bytes,14,opt,name=provider,proto3" json:"provider"` + // Flag indicating whether the consumer CCV module starts in pre-CCV state + PreCCV bool `protobuf:"varint,13,opt,name=preCCV,proto3" json:"preCCV,omitempty"` + Provider types.ProviderInfo `protobuf:"bytes,14,opt,name=provider,proto3" json:"provider"` + // The ID of the connection end on the consumer chain on top of which the + // CCV channel will be established. If connection_id == "", a new client of + // the provider chain and a new connection on top of this client are created. + // The new client is initialized using provider.client_state and provider.consensus_state. + ConnectionId string `protobuf:"bytes,15,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -182,6 +189,13 @@ func (m *GenesisState) GetLastTransmissionBlockHeight() LastTransmissionBlockHei return LastTransmissionBlockHeight{} } +func (m *GenesisState) GetPreCCV() bool { + if m != nil { + return m.PreCCV + } + return false +} + func (m *GenesisState) GetProvider() types.ProviderInfo { if m != nil { return m.Provider @@ -189,6 +203,13 @@ func (m *GenesisState) GetProvider() types.ProviderInfo { return types.ProviderInfo{} } +func (m *GenesisState) GetConnectionId() string { + if m != nil { + return m.ConnectionId + } + return "" +} + // HeightValsetUpdateID represents a mapping internal to the consumer CCV module // which links a block height to each recv valset update id. type HeightToValsetUpdateID struct { @@ -454,64 +475,66 @@ func init() { } var fileDescriptor_2db73a6057a27482 = []byte{ - // 904 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcf, 0x6f, 0x23, 0x35, - 0x14, 0xee, 0xb4, 0xd9, 0x90, 0xb8, 0x3f, 0xb6, 0xeb, 0x2e, 0xd1, 0xd0, 0x88, 0x34, 0x0a, 0x42, - 0x8a, 0xf8, 0xe1, 0x21, 0x45, 0xac, 0x90, 0x10, 0x08, 0xd2, 0x4a, 0x34, 0xab, 0x45, 0x54, 0x69, - 0xb7, 0x48, 0x7b, 0x19, 0x39, 0x1e, 0xef, 0xc4, 0xda, 0x19, 0x3b, 0x1a, 0x7b, 0x26, 0x54, 0x88, - 0x0b, 0x57, 0x2e, 0xfb, 0x37, 0x71, 0xda, 0xe3, 0x1e, 0x39, 0x01, 0x6a, 0xff, 0x11, 0x64, 0x8f, - 0x67, 0x92, 0xb4, 0x69, 0x37, 0xb7, 0xf1, 0xbc, 0xf7, 0xbe, 0xef, 0xbd, 0xef, 0x3d, 0xfb, 0x81, - 0x1e, 0xe3, 0x8a, 0x26, 0x64, 0x8c, 0x19, 0xf7, 0x25, 0x25, 0x69, 0xc2, 0xd4, 0xa5, 0x47, 0x48, - 0xe6, 0x11, 0xc1, 0x65, 0x1a, 0xd3, 0xc4, 0xcb, 0x7a, 0x5e, 0x48, 0x39, 0x95, 0x4c, 0xa2, 0x49, - 0x22, 0x94, 0x80, 0x1f, 0x2d, 0x09, 0x41, 0x84, 0x64, 0xa8, 0x08, 0x41, 0x59, 0x6f, 0xff, 0x8b, - 0xbb, 0x70, 0xb3, 0x9e, 0x27, 0xc7, 0x38, 0xa1, 0x81, 0x5f, 0xba, 0x1b, 0xd8, 0x7d, 0x8f, 0x8d, - 0x88, 0x17, 0xb1, 0x70, 0xac, 0x48, 0xc4, 0x28, 0x57, 0xd2, 0x53, 0x94, 0x07, 0x34, 0x89, 0x19, - 0x57, 0x3a, 0x6a, 0x76, 0xb2, 0x01, 0x8f, 0x43, 0x11, 0x0a, 0xf3, 0xe9, 0xe9, 0x2f, 0xfb, 0xf7, - 0xe3, 0x7b, 0x88, 0xa7, 0x2c, 0xa1, 0xd6, 0xed, 0x20, 0x14, 0x22, 0x8c, 0xa8, 0x67, 0x4e, 0xa3, - 0xf4, 0xa5, 0xa7, 0x58, 0x4c, 0xa5, 0xc2, 0xf1, 0xc4, 0x3a, 0x34, 0xe7, 0xd8, 0xf1, 0x88, 0x30, - 0x4f, 0x5d, 0x4e, 0xa8, 0x95, 0xa0, 0xf3, 0x57, 0x1d, 0x6c, 0xfd, 0x98, 0x8b, 0x72, 0xa6, 0xb0, - 0xa2, 0xf0, 0x04, 0x54, 0x27, 0x38, 0xc1, 0xb1, 0x74, 0x9d, 0xb6, 0xd3, 0xdd, 0x3c, 0xfc, 0x04, - 0xdd, 0x25, 0x52, 0xd6, 0x43, 0x47, 0xb6, 0xf0, 0x53, 0x13, 0xd1, 0xaf, 0xbc, 0xf9, 0xe7, 0x60, - 0x6d, 0x68, 0xe3, 0xe1, 0x67, 0x00, 0x4e, 0x12, 0x91, 0xb1, 0x80, 0x26, 0x7e, 0x2e, 0x84, 0xcf, - 0x02, 0x77, 0xbd, 0xed, 0x74, 0xeb, 0xc3, 0xdd, 0xc2, 0x72, 0x64, 0x0c, 0x83, 0x00, 0x22, 0xb0, - 0x37, 0xf3, 0x1e, 0x63, 0xce, 0x69, 0xa4, 0xdd, 0x37, 0x8c, 0xfb, 0xa3, 0xd2, 0x3d, 0xb7, 0x0c, - 0x02, 0xd8, 0x04, 0x75, 0x4e, 0xa7, 0xbe, 0xc9, 0xcb, 0xad, 0xb4, 0x9d, 0x6e, 0x6d, 0x58, 0xe3, - 0x74, 0x7a, 0xa4, 0xcf, 0x90, 0x80, 0xf7, 0x6f, 0x52, 0x4b, 0x5d, 0x9d, 0xfb, 0xc0, 0xd4, 0xf4, - 0x29, 0x62, 0x23, 0x82, 0xe6, 0x3b, 0x84, 0xe6, 0x7a, 0xa2, 0xeb, 0x32, 0x7f, 0x8d, 0x20, 0xfd, - 0x75, 0xd7, 0x19, 0xee, 0x2d, 0xa6, 0x9b, 0x2b, 0x15, 0x01, 0x77, 0x46, 0x22, 0xb8, 0xa4, 0x5c, - 0xa6, 0xd2, 0xf2, 0x54, 0x0d, 0x0f, 0x7a, 0x27, 0x4f, 0x11, 0x36, 0xa3, 0x6a, 0x94, 0x54, 0x0b, - 0x36, 0x18, 0x82, 0xdd, 0x18, 0xab, 0x34, 0x61, 0x3c, 0xf4, 0x27, 0x98, 0xbc, 0xa2, 0x4a, 0xba, - 0xef, 0xb5, 0x37, 0xba, 0x9b, 0x87, 0x4f, 0xd0, 0x0a, 0x63, 0x8c, 0x7e, 0xb2, 0xc1, 0x17, 0x67, - 0x47, 0xa7, 0x26, 0xdc, 0x76, 0xeb, 0x61, 0x81, 0x9a, 0xff, 0x95, 0xf0, 0x14, 0x3c, 0x64, 0x9c, - 0x29, 0x86, 0x23, 0x3f, 0xc3, 0x91, 0x2f, 0xa9, 0x72, 0x6b, 0x86, 0xa7, 0x3d, 0x9f, 0xbc, 0x1e, - 0x24, 0x74, 0x81, 0x23, 0x16, 0x60, 0x25, 0x92, 0xe7, 0x93, 0x40, 0xe7, 0x5f, 0xd5, 0x88, 0xae, - 0x33, 0xdc, 0xb6, 0x00, 0x17, 0x38, 0x3a, 0xa3, 0x0a, 0xfe, 0x0e, 0xf6, 0xc7, 0x54, 0x8b, 0xe0, - 0x2b, 0xa1, 0x31, 0x25, 0x55, 0x7e, 0x6a, 0x22, 0x74, 0x87, 0xeb, 0x06, 0xfc, 0x9b, 0x95, 0x8a, - 0x38, 0x31, 0x30, 0xe7, 0xe2, 0xc2, 0x80, 0xe4, 0xac, 0x83, 0x63, 0x5b, 0x49, 0x63, 0xbc, 0xcc, - 0x1a, 0xc0, 0x3f, 0x1c, 0xf0, 0xa1, 0x48, 0x95, 0x54, 0x98, 0x07, 0x5a, 0xbd, 0x40, 0x4c, 0xb9, - 0xbe, 0x23, 0xbe, 0x8c, 0xb0, 0x1c, 0x33, 0x1e, 0xba, 0xc0, 0xa4, 0xf0, 0xf5, 0x4a, 0x29, 0xfc, - 0x3c, 0x43, 0x3a, 0xb6, 0x40, 0x96, 0xbf, 0x29, 0x6e, 0x9b, 0xce, 0x2c, 0x05, 0xfc, 0x0d, 0xb8, - 0x13, 0x9a, 0xf3, 0x17, 0x68, 0x65, 0x1b, 0x37, 0xcd, 0xb0, 0xac, 0xa6, 0xc0, 0xec, 0xc6, 0xe9, - 0xd8, 0x63, 0xac, 0xf0, 0x33, 0x26, 0x8b, 0x5e, 0x36, 0x2c, 0xc5, 0xa2, 0x93, 0x84, 0x7f, 0x3a, - 0xa0, 0x15, 0x61, 0xa9, 0x7c, 0x95, 0x60, 0x2e, 0x63, 0x26, 0x25, 0x13, 0xdc, 0x1f, 0x45, 0x82, - 0xbc, 0xf2, 0x73, 0xd1, 0xdc, 0x2d, 0x93, 0xc3, 0xf7, 0x2b, 0xe5, 0xf0, 0x0c, 0x4b, 0x75, 0x3e, - 0x87, 0xd4, 0xd7, 0x40, 0x79, 0x6b, 0x0a, 0x29, 0xa2, 0xbb, 0x5d, 0xe0, 0x53, 0x50, 0x2b, 0x66, - 0xdc, 0xdd, 0x31, 0xb4, 0xdd, 0xfb, 0xde, 0x98, 0x53, 0xeb, 0x3b, 0xe0, 0x2f, 0x85, 0x85, 0x2f, - 0xe3, 0x9f, 0x56, 0x6a, 0xdb, 0xbb, 0x3b, 0x9d, 0x17, 0xa0, 0xb1, 0x7c, 0x32, 0x60, 0x03, 0x54, - 0x6d, 0x81, 0xfa, 0x35, 0xab, 0x0c, 0xed, 0x09, 0x76, 0xc1, 0xee, 0xad, 0x41, 0x5c, 0x37, 0x1e, - 0x3b, 0xd9, 0xc2, 0xf4, 0x74, 0x9e, 0x83, 0xbd, 0x25, 0x2d, 0x87, 0xdf, 0x81, 0x66, 0x56, 0x4c, - 0xff, 0xdc, 0xed, 0xc7, 0x41, 0x90, 0x50, 0x99, 0xbf, 0x9d, 0xf5, 0xe1, 0x07, 0xa5, 0x4b, 0x79, - 0x99, 0x7f, 0xc8, 0x1d, 0x3a, 0x5f, 0x81, 0xe6, 0x3d, 0x32, 0xde, 0xc8, 0x7b, 0xa3, 0xc8, 0xbb, - 0xa3, 0xc0, 0xa3, 0x5b, 0x17, 0x19, 0x3e, 0x06, 0x0f, 0x32, 0x49, 0x06, 0x81, 0xad, 0x31, 0x3f, - 0xc0, 0x01, 0xd8, 0xce, 0xaf, 0xb6, 0xba, 0xf4, 0x75, 0xca, 0xa6, 0xbe, 0xcd, 0xc3, 0x7d, 0x94, - 0xef, 0x0b, 0x54, 0xec, 0x0b, 0x74, 0x5e, 0xec, 0x8b, 0x7e, 0x4d, 0xab, 0xfb, 0xfa, 0xdf, 0x03, - 0x67, 0xb8, 0x55, 0x84, 0x6a, 0x63, 0x67, 0x04, 0x1a, 0xcb, 0xe7, 0x0e, 0x9e, 0x80, 0x4a, 0xc4, - 0xa4, 0xce, 0x72, 0x23, 0x7f, 0xef, 0x56, 0xd9, 0x15, 0x05, 0x82, 0xed, 0xa6, 0x41, 0xe8, 0xff, - 0xf2, 0xe6, 0xaa, 0xe5, 0xbc, 0xbd, 0x6a, 0x39, 0xff, 0x5d, 0xb5, 0x9c, 0xd7, 0xd7, 0xad, 0xb5, - 0xb7, 0xd7, 0xad, 0xb5, 0xbf, 0xaf, 0x5b, 0x6b, 0x2f, 0xbe, 0x0d, 0x99, 0x1a, 0xa7, 0x23, 0x44, - 0x44, 0xec, 0x11, 0x21, 0x63, 0x21, 0xbd, 0x19, 0xcd, 0xe7, 0xe5, 0x66, 0xcc, 0x9e, 0x78, 0xbf, - 0x2e, 0xee, 0x7b, 0xb3, 0xe7, 0x46, 0x55, 0x53, 0xe8, 0x97, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, - 0x07, 0xc0, 0xce, 0x30, 0x20, 0x08, 0x00, 0x00, + // 932 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcf, 0x6f, 0x23, 0x35, + 0x14, 0xee, 0xb4, 0xdd, 0x90, 0xb8, 0xed, 0xb6, 0xeb, 0x2e, 0xd1, 0xd0, 0x88, 0x34, 0xca, 0x0a, + 0x29, 0xe2, 0x87, 0x87, 0x14, 0xb1, 0x42, 0x42, 0x20, 0x48, 0x2a, 0xd1, 0xa0, 0x22, 0xaa, 0xb4, + 0x1b, 0xa4, 0xbd, 0x8c, 0x1c, 0x8f, 0x77, 0x62, 0xed, 0x8c, 0x3d, 0x1a, 0x3b, 0x53, 0x2a, 0xc4, + 0x85, 0x2b, 0x97, 0xfd, 0xb3, 0xf6, 0xd8, 0x23, 0x27, 0x40, 0xed, 0x5f, 0xc1, 0x0d, 0xd9, 0xe3, + 0xc9, 0x24, 0x34, 0x2d, 0xb9, 0xc5, 0xf3, 0xde, 0xfb, 0xbe, 0xf7, 0xbe, 0xf7, 0xfc, 0x1c, 0xd0, + 0x65, 0x5c, 0xd1, 0x94, 0x4c, 0x30, 0xe3, 0xbe, 0xa4, 0x64, 0x9a, 0x32, 0x75, 0xe5, 0x11, 0x92, + 0x79, 0x44, 0x70, 0x39, 0x8d, 0x69, 0xea, 0x65, 0x5d, 0x2f, 0xa4, 0x9c, 0x4a, 0x26, 0x51, 0x92, + 0x0a, 0x25, 0xe0, 0xb3, 0x25, 0x21, 0x88, 0x90, 0x0c, 0x15, 0x21, 0x28, 0xeb, 0x1e, 0x7c, 0x7a, + 0x1f, 0x6e, 0xd6, 0xf5, 0xe4, 0x04, 0xa7, 0x34, 0xf0, 0x67, 0xee, 0x06, 0xf6, 0xc0, 0x63, 0x63, + 0xe2, 0x45, 0x2c, 0x9c, 0x28, 0x12, 0x31, 0xca, 0x95, 0xf4, 0x14, 0xe5, 0x01, 0x4d, 0x63, 0xc6, + 0x95, 0x8e, 0x2a, 0x4f, 0x36, 0xe0, 0x69, 0x28, 0x42, 0x61, 0x7e, 0x7a, 0xfa, 0x97, 0xfd, 0xfa, + 0xc1, 0x03, 0xc4, 0x97, 0x2c, 0xa5, 0xd6, 0xed, 0x30, 0x14, 0x22, 0x8c, 0xa8, 0x67, 0x4e, 0xe3, + 0xe9, 0x2b, 0x4f, 0xb1, 0x98, 0x4a, 0x85, 0xe3, 0xc4, 0x3a, 0x34, 0xe6, 0xd8, 0xf1, 0x98, 0x30, + 0x4f, 0x5d, 0x25, 0xd4, 0x4a, 0xd0, 0xfe, 0xa7, 0x06, 0xb6, 0xbf, 0xcb, 0x45, 0x39, 0x57, 0x58, + 0x51, 0x78, 0x02, 0x2a, 0x09, 0x4e, 0x71, 0x2c, 0x5d, 0xa7, 0xe5, 0x74, 0xb6, 0x8e, 0x3e, 0x44, + 0xf7, 0x89, 0x94, 0x75, 0x51, 0xdf, 0x16, 0x7e, 0x66, 0x22, 0x7a, 0x9b, 0x6f, 0xff, 0x3c, 0x5c, + 0x1b, 0xda, 0x78, 0xf8, 0x31, 0x80, 0x49, 0x2a, 0x32, 0x16, 0xd0, 0xd4, 0xcf, 0x85, 0xf0, 0x59, + 0xe0, 0xae, 0xb7, 0x9c, 0x4e, 0x6d, 0xb8, 0x57, 0x58, 0xfa, 0xc6, 0x30, 0x08, 0x20, 0x02, 0xfb, + 0xa5, 0xf7, 0x04, 0x73, 0x4e, 0x23, 0xed, 0xbe, 0x61, 0xdc, 0x9f, 0xcc, 0xdc, 0x73, 0xcb, 0x20, + 0x80, 0x0d, 0x50, 0xe3, 0xf4, 0xd2, 0x37, 0x79, 0xb9, 0x9b, 0x2d, 0xa7, 0x53, 0x1d, 0x56, 0x39, + 0xbd, 0xec, 0xeb, 0x33, 0x24, 0xe0, 0xdd, 0xff, 0x52, 0x4b, 0x5d, 0x9d, 0xfb, 0xc8, 0xd4, 0xf4, + 0x11, 0x62, 0x63, 0x82, 0xe6, 0x3b, 0x84, 0xe6, 0x7a, 0xa2, 0xeb, 0x32, 0x5f, 0x8d, 0x20, 0xbd, + 0x75, 0xd7, 0x19, 0xee, 0x2f, 0xa6, 0x9b, 0x2b, 0x15, 0x01, 0xb7, 0x24, 0x11, 0x5c, 0x52, 0x2e, + 0xa7, 0xd2, 0xf2, 0x54, 0x0c, 0x0f, 0xfa, 0x5f, 0x9e, 0x22, 0xac, 0xa4, 0xaa, 0xcf, 0xa8, 0x16, + 0x6c, 0x30, 0x04, 0x7b, 0x31, 0x56, 0xd3, 0x94, 0xf1, 0xd0, 0x4f, 0x30, 0x79, 0x4d, 0x95, 0x74, + 0xdf, 0x69, 0x6d, 0x74, 0xb6, 0x8e, 0x9e, 0xa3, 0x15, 0xc6, 0x18, 0xfd, 0x60, 0x83, 0x47, 0xe7, + 0xfd, 0x33, 0x13, 0x6e, 0xbb, 0xb5, 0x5b, 0xa0, 0xe6, 0x5f, 0x25, 0x3c, 0x03, 0xbb, 0x8c, 0x33, + 0xc5, 0x70, 0xe4, 0x67, 0x38, 0xf2, 0x25, 0x55, 0x6e, 0xd5, 0xf0, 0xb4, 0xe6, 0x93, 0xd7, 0x83, + 0x84, 0x46, 0x38, 0x62, 0x01, 0x56, 0x22, 0x7d, 0x91, 0x04, 0x3a, 0xff, 0x8a, 0x46, 0x74, 0x9d, + 0xe1, 0x8e, 0x05, 0x18, 0xe1, 0xe8, 0x9c, 0x2a, 0xf8, 0x2b, 0x38, 0x98, 0x50, 0x2d, 0x82, 0xaf, + 0x84, 0xc6, 0x94, 0x54, 0xf9, 0x53, 0x13, 0xa1, 0x3b, 0x5c, 0x33, 0xe0, 0x5f, 0xae, 0x54, 0xc4, + 0x89, 0x81, 0xb9, 0x10, 0x23, 0x03, 0x92, 0xb3, 0x0e, 0x8e, 0x6d, 0x25, 0xf5, 0xc9, 0x32, 0x6b, + 0x00, 0x7f, 0x73, 0xc0, 0xfb, 0x62, 0xaa, 0xa4, 0xc2, 0x3c, 0xd0, 0xea, 0x05, 0xe2, 0x92, 0xeb, + 0x3b, 0xe2, 0xcb, 0x08, 0xcb, 0x09, 0xe3, 0xa1, 0x0b, 0x4c, 0x0a, 0x5f, 0xac, 0x94, 0xc2, 0x8f, + 0x25, 0xd2, 0xb1, 0x05, 0xb2, 0xfc, 0x0d, 0x71, 0xd7, 0x74, 0x6e, 0x29, 0xe0, 0x2f, 0xc0, 0x4d, + 0x68, 0xce, 0x5f, 0xa0, 0xcd, 0xda, 0xb8, 0x65, 0x86, 0x65, 0x35, 0x05, 0xca, 0x1b, 0xa7, 0x63, + 0x8f, 0xb1, 0xc2, 0xa7, 0x4c, 0x16, 0xbd, 0xac, 0x5b, 0x8a, 0x45, 0x27, 0x09, 0x7f, 0x77, 0x40, + 0x33, 0xc2, 0x52, 0xf9, 0x2a, 0xc5, 0x5c, 0xc6, 0x4c, 0x4a, 0x26, 0xb8, 0x3f, 0x8e, 0x04, 0x79, + 0xed, 0xe7, 0xa2, 0xb9, 0xdb, 0x26, 0x87, 0x6f, 0x56, 0xca, 0xe1, 0x14, 0x4b, 0x75, 0x31, 0x87, + 0xd4, 0xd3, 0x40, 0x79, 0x6b, 0x0a, 0x29, 0xa2, 0xfb, 0x5d, 0x60, 0x1d, 0x54, 0x92, 0x94, 0xf6, + 0xfb, 0x23, 0x77, 0xc7, 0x5c, 0x5b, 0x7b, 0x82, 0xdf, 0x83, 0x6a, 0x31, 0xfb, 0xee, 0x63, 0x93, + 0x4e, 0xe7, 0xa1, 0xdd, 0x73, 0x66, 0x7d, 0x07, 0xfc, 0x95, 0xb0, 0xb4, 0xb3, 0x78, 0xf8, 0x0c, + 0xec, 0x10, 0xc1, 0x39, 0x25, 0x4a, 0x57, 0xca, 0x02, 0x77, 0xd7, 0xec, 0x91, 0xed, 0xf2, 0xe3, + 0x20, 0x68, 0xbf, 0x04, 0xf5, 0xe5, 0x03, 0xa5, 0x53, 0xb4, 0xba, 0xe8, 0x25, 0xb8, 0x39, 0xb4, + 0x27, 0xd8, 0x01, 0x7b, 0x77, 0xe6, 0x77, 0xdd, 0x78, 0x3c, 0xce, 0x16, 0x86, 0xae, 0xfd, 0x02, + 0xec, 0x2f, 0x99, 0x14, 0xf8, 0x35, 0x68, 0x64, 0xc5, 0xa5, 0x99, 0x5b, 0x1a, 0x38, 0x08, 0x52, + 0x2a, 0xf3, 0x95, 0x5b, 0x1b, 0xbe, 0x37, 0x73, 0x99, 0xed, 0x80, 0x6f, 0x73, 0x87, 0xf6, 0xe7, + 0xa0, 0x71, 0xfa, 0xb0, 0xb4, 0x73, 0x79, 0x6f, 0x14, 0x79, 0xb7, 0x15, 0x78, 0x72, 0xe7, 0xfe, + 0xc3, 0xa7, 0xe0, 0x51, 0x26, 0xc9, 0x20, 0xb0, 0x35, 0xe6, 0x07, 0x38, 0x00, 0x3b, 0xf9, 0x46, + 0x50, 0x57, 0xbe, 0x4e, 0xd9, 0xd4, 0xb7, 0x75, 0x74, 0x80, 0xf2, 0x67, 0x06, 0x15, 0xcf, 0x0c, + 0xba, 0x28, 0x9e, 0x99, 0x5e, 0x55, 0x8b, 0xff, 0xe6, 0xaf, 0x43, 0x67, 0xb8, 0x5d, 0x84, 0x6a, + 0x63, 0x7b, 0x0c, 0xea, 0xcb, 0xc7, 0x15, 0x9e, 0x80, 0xcd, 0x88, 0x49, 0x9d, 0xe5, 0x46, 0xbe, + 0x26, 0x57, 0x79, 0x62, 0x0a, 0x04, 0xdb, 0x6c, 0x83, 0xd0, 0xfb, 0xe9, 0xed, 0x4d, 0xd3, 0xb9, + 0xbe, 0x69, 0x3a, 0x7f, 0xdf, 0x34, 0x9d, 0x37, 0xb7, 0xcd, 0xb5, 0xeb, 0xdb, 0xe6, 0xda, 0x1f, + 0xb7, 0xcd, 0xb5, 0x97, 0x5f, 0x85, 0x4c, 0x4d, 0xa6, 0x63, 0x44, 0x44, 0xec, 0x11, 0x21, 0x63, + 0x21, 0xbd, 0x92, 0xe6, 0x93, 0xd9, 0x83, 0x9a, 0x3d, 0xf7, 0x7e, 0x5e, 0xfc, 0x9b, 0x60, 0x9e, + 0xc7, 0x71, 0xc5, 0x14, 0xfa, 0xd9, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x51, 0x4a, 0x27, 0x28, + 0x57, 0x08, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -534,6 +557,13 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x7a + } { size, err := m.Provider.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -544,6 +574,16 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x72 + if m.PreCCV { + i-- + if m.PreCCV { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x68 + } { size, err := m.LastTransmissionBlockHeight.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -911,8 +951,15 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) l = m.LastTransmissionBlockHeight.Size() n += 1 + l + sovGenesis(uint64(l)) + if m.PreCCV { + n += 2 + } l = m.Provider.Size() n += 1 + l + sovGenesis(uint64(l)) + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -1411,6 +1458,26 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PreCCV = bool(v != 0) case 14: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Provider", wireType) @@ -1444,6 +1511,38 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", 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.ConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index cc04a9f487..b77ee85f1a 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -94,13 +94,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, }, true, }, @@ -115,13 +115,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, }, true, }, @@ -136,13 +136,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: []types.MaturingVSCPacket{{}}, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, }, true, }, @@ -157,13 +157,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{Height: 1}, + PreCCV: false, }, true, }, @@ -178,13 +178,13 @@ func TestValidateInitialGenesisState(t *testing.T) { ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{List: []ccv.ConsumerPacketData{{}}}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, }, true, }, @@ -369,13 +369,13 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { ClientState: cs, ConsensusState: nil, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, }, true, }, @@ -390,13 +390,13 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { ClientState: nil, ConsensusState: consensusState, InitialValSet: valUpdates, - PreCCV: false, }, MaturingPackets: nil, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, }, true, }, diff --git a/x/ccv/provider/keeper/consumer_lifecycle.go b/x/ccv/provider/keeper/consumer_lifecycle.go index 51d2120f89..abfbf2351e 100644 --- a/x/ccv/provider/keeper/consumer_lifecycle.go +++ b/x/ccv/provider/keeper/consumer_lifecycle.go @@ -349,39 +349,60 @@ func (k Keeper) MakeConsumerGenesis( consumerId, ) - // create provider client state and consensus state for the consumer to be able - // to create a provider client + var clientState *ibctmtypes.ClientState = nil + var tmConsState *ibctmtypes.ConsensusState = nil + var preCCV bool + var counterpartyConnectionId string - providerUnbondingPeriod, err := k.stakingKeeper.UnbondingTime(ctx) - if err != nil { - return gen, errorsmod.Wrapf(types.ErrNoUnbondingTime, "unbonding time not found: %s", err) - } - height := clienttypes.GetSelfHeight(ctx) + if initializationRecord.ConnectionId == "" { + // no connection ID provided + preCCV = false + counterpartyConnectionId = "" - clientState := k.GetTemplateClient(ctx) - // this is the counter party chain ID for the consumer - clientState.ChainId = ctx.ChainID() - // this is the latest height the client was updated at, i.e., - // the height of the latest consensus state (see below) - clientState.LatestHeight = height - trustPeriod, err := ccv.CalculateTrustPeriod(providerUnbondingPeriod, k.GetTrustingPeriodFraction(ctx)) - if err != nil { - return gen, errorsmod.Wrapf(sdkerrors.ErrInvalidHeight, "error %s calculating trusting_period for: %s", err, height) - } - clientState.TrustingPeriod = trustPeriod - clientState.UnbondingPeriod = providerUnbondingPeriod + // create provider client state and consensus state for the consumer to be able + // to create a provider client - consState, err := k.clientKeeper.GetSelfConsensusState(ctx, height) - if err != nil { - return gen, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) + providerUnbondingPeriod, err := k.stakingKeeper.UnbondingTime(ctx) + if err != nil { + return gen, errorsmod.Wrapf(types.ErrNoUnbondingTime, "unbonding time not found: %s", err) + } + height := clienttypes.GetSelfHeight(ctx) + + clientState = k.GetTemplateClient(ctx) + // this is the counter party chain ID for the consumer + clientState.ChainId = ctx.ChainID() + // this is the latest height the client was updated at, i.e., + // the height of the latest consensus state (see below) + clientState.LatestHeight = height + trustPeriod, err := ccv.CalculateTrustPeriod(providerUnbondingPeriod, k.GetTrustingPeriodFraction(ctx)) + if err != nil { + return gen, errorsmod.Wrapf(sdkerrors.ErrInvalidHeight, "error %s calculating trusting_period for: %s", err, height) + } + clientState.TrustingPeriod = trustPeriod + clientState.UnbondingPeriod = providerUnbondingPeriod + + consState, err := k.clientKeeper.GetSelfConsensusState(ctx, height) + if err != nil { + return gen, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) + } + tmConsState = consState.(*ibctmtypes.ConsensusState) + } else { + // connection ID provided + preCCV = true + // TODO + // check validity + // connectionEnd.counterpartyConnectionIdentifier, } gen = *ccv.NewInitialConsumerGenesisState( clientState, - consState.(*ibctmtypes.ConsensusState), + tmConsState, initialValidatorUpdates, + preCCV, + counterpartyConnectionId, consumerGenesisParams, ) + return gen, nil } diff --git a/x/ccv/provider/types/genesis.go b/x/ccv/provider/types/genesis.go index e3cc478e2e..0a01b7c19b 100644 --- a/x/ccv/provider/types/genesis.go +++ b/x/ccv/provider/types/genesis.go @@ -81,10 +81,6 @@ func (cs ConsumerState) Validate() error { if err := host.ClientIdentifierValidator(cs.ClientId); err != nil { return err } - // consumer genesis should be for a new chain only - if !cs.ConsumerGenesis.NewChain { - return fmt.Errorf("consumer genesis must be for a new chain") - } // validate a new chain genesis if err := cs.ConsumerGenesis.Validate(); err != nil { return err diff --git a/x/ccv/provider/types/genesis_test.go b/x/ccv/provider/types/genesis_test.go index 1539d1a5fe..4fdbd7c26f 100644 --- a/x/ccv/provider/types/genesis_test.go +++ b/x/ccv/provider/types/genesis_test.go @@ -33,7 +33,7 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}}, + []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, types.DefaultParams(), nil, nil, @@ -47,10 +47,10 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{ - {ChainId: "chainid-1", ChannelId: "channelid1", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}, - {ChainId: "chainid-2", ChannelId: "channelid2", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-2")}, - {ChainId: "chainid-3", ChannelId: "channelid3", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-3")}, - {ChainId: "chainid-4", ChannelId: "channelid4", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-4")}, + {ChainId: "chainid-1", ChannelId: "channelid1", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}, + {ChainId: "chainid-2", ChannelId: "channelid2", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-2", true)}, + {ChainId: "chainid-3", ChannelId: "channelid3", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-3", false)}, + {ChainId: "chainid-4", ChannelId: "channelid4", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-4", true)}, }, types.DefaultParams(), nil, @@ -64,9 +64,8 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, + types.NewParams(types.DefaultTemplateClient(), types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24, 180), nil, nil, @@ -80,9 +79,7 @@ func TestValidateGenesisState(t *testing.T) { 0, nil, nil, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24, 180), + types.DefaultParams(), nil, nil, nil, @@ -95,28 +92,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, []types.ValsetUpdateIdToHeight{{ValsetUpdateId: 0}}, nil, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24, 180), - nil, - nil, - nil, - ), - false, - }, - { - "invalid params", - types.NewGenesisState( - types.DefaultValsetUpdateID, - nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, - ccv.DefaultCCVTimeoutPeriod, - types.DefaultSlashMeterReplenishPeriod, - types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24, 180), + types.DefaultParams(), nil, nil, nil, @@ -129,8 +105,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + types.NewParams(types.DefaultTemplateClient(), "0.0", // 0 trusting period fraction here ccv.DefaultCCVTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, @@ -148,8 +123,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + types.NewParams(types.DefaultTemplateClient(), types.DefaultTrustingPeriodFraction, 0, // 0 ccv timeout here types.DefaultSlashMeterReplenishPeriod, @@ -167,8 +141,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + types.NewParams(types.DefaultTemplateClient(), types.DefaultTrustingPeriodFraction, ccv.DefaultCCVTimeoutPeriod, 0, // 0 slash meter replenish period here @@ -186,8 +159,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + types.NewParams(types.DefaultTemplateClient(), types.DefaultTrustingPeriodFraction, ccv.DefaultCCVTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, @@ -199,25 +171,12 @@ func TestValidateGenesisState(t *testing.T) { ), false, }, - { - "invalid consumer state chain id", - types.NewGenesisState( - types.DefaultValsetUpdateID, - nil, - []types.ConsumerState{{ChainId: "", ChannelId: "channelid", ClientId: "client-id"}}, - types.DefaultParams(), - nil, - nil, - nil, - ), - false, - }, { "invalid consumer state channel id", types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid", ChannelId: "ivnalidChannel{}", ClientId: "client-id"}}, + []types.ConsumerState{{ChainId: "chainid", ChannelId: "invalidChannel{}", ClientId: "client-id"}}, types.DefaultParams(), nil, nil, @@ -243,23 +202,7 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid", ChannelId: "channel-0", ClientId: "abc", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid")}}, - types.DefaultParams(), - nil, - nil, - nil, - ), - false, - }, - { - "empty consumer state consumer genesis", - types.NewGenesisState( - types.DefaultValsetUpdateID, - nil, - []types.ConsumerState{{ - ChainId: "chainid", ChannelId: "channel-0", ClientId: "client-id", - ConsumerGenesis: ccv.ConsumerGenesisState{}, - }}, + []types.ConsumerState{{ChainId: "chainid", ChannelId: "channel-0", ClientId: "abc", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false)}}, types.DefaultParams(), nil, nil, @@ -274,7 +217,7 @@ func TestValidateGenesisState(t *testing.T) { nil, []types.ConsumerState{{ ChainId: "chainid", ChannelId: "channel-0", ClientId: "client-id", - ConsumerGenesis: getInitialConsumerGenesis(t, "chainid"), + ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false), SlashDowntimeAck: []string{"cosmosvaloper1qlmk6r5w5taqrky4ycur4zq6jqxmuzr688htpp"}, }}, types.DefaultParams(), @@ -291,7 +234,7 @@ func TestValidateGenesisState(t *testing.T) { nil, []types.ConsumerState{{ ChainId: "chainid", ChannelId: "channel-0", ClientId: "client-id", - ConsumerGenesis: getInitialConsumerGenesis(t, "chainid"), + ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false), PendingValsetChanges: []ccv.ValidatorSetChangePacketData{{}}, }}, types.DefaultParams(), @@ -308,7 +251,7 @@ func TestValidateGenesisState(t *testing.T) { nil, []types.ConsumerState{{ ChainId: "chainid", ChannelId: "channel-0", ClientId: "client-id", - ConsumerGenesis: getInitialConsumerGenesis(t, "chainid"), + ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false), PendingValsetChanges: []ccv.ValidatorSetChangePacketData{{ SlashAcks: []string{"cosmosvaloper1qlmk6r5w5taqrky4ycur4zq6jqxmuzr688htpp"}, ValsetUpdateId: 1, @@ -327,9 +270,8 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, + types.NewParams(types.DefaultTemplateClient(), types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 600, 24, 180), nil, nil, @@ -342,9 +284,8 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1")}}, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, + types.NewParams(types.DefaultTemplateClient(), types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}, 600, 24, 180), nil, nil, @@ -367,7 +308,7 @@ func TestValidateGenesisState(t *testing.T) { } } -func getInitialConsumerGenesis(t *testing.T, chainID string) ccv.ConsumerGenesisState { +func getInitialConsumerGenesis(t *testing.T, chainID string, preCCV bool) ccv.ConsumerGenesisState { t.Helper() // generate validator public key cId := crypto.NewCryptoIdentityFromIntSeed(239668) @@ -379,18 +320,27 @@ func getInitialConsumerGenesis(t *testing.T, chainID string) ccv.ConsumerGenesis valHash := valSet.Hash() valUpdates := tmtypes.TM2PB.ValidatorUpdates(valSet) - cs := ibctmtypes.NewClientState( - chainID, - ibctmtypes.DefaultTrustLevel, - time.Duration(1), - time.Duration(2), - time.Duration(1), - clienttypes.Height{RevisionNumber: clienttypes.ParseChainID(chainID), RevisionHeight: 1}, - commitmenttypes.GetSDKSpecs(), - []string{"upgrade", "upgradedIBCState"}) - consensusState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), valHash) + var clientState *ibctmtypes.ClientState = nil + var consensusState *ibctmtypes.ConsensusState = nil + connectionId := "" + + if preCCV { + connectionId = "connection-1" + } else { + clientState = ibctmtypes.NewClientState( + chainID, + ibctmtypes.DefaultTrustLevel, + time.Duration(1), + time.Duration(2), + time.Duration(1), + clienttypes.Height{RevisionNumber: clienttypes.ParseChainID(chainID), RevisionHeight: 1}, + commitmenttypes.GetSDKSpecs(), + []string{"upgrade", "upgradedIBCState"}) + consensusState = ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), valHash) + } params := ccv.DefaultParams() params.Enabled = true - return *ccv.NewInitialConsumerGenesisState(cs, consensusState, valUpdates, params) + + return *ccv.NewInitialConsumerGenesisState(clientState, consensusState, valUpdates, preCCV, connectionId, params) } diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 0e7445e42c..156d0a74b0 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" - ibchost "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" @@ -593,7 +592,7 @@ func ValidateInitializationParameters(initializationParameters ConsumerInitializ return errorsmod.Wrapf(ErrInvalidConsumerInitializationParameters, "UnbondingPeriod: %s", err.Error()) } - if err := ValidateConnectionIdentifier(initializationParameters.ConnectionId); err != nil { + if err := ccvtypes.ValidateConnectionIdentifier(initializationParameters.ConnectionId); err != nil { return errorsmod.Wrapf(ErrInvalidConsumerInitializationParameters, "ConnectionId: %s", err.Error()) } @@ -638,11 +637,3 @@ func ValidateInitialHeight(initialHeight clienttypes.Height, chainID string) err } return nil } - -func ValidateConnectionIdentifier(connId string) error { - // accept empty string as valid - if connId == "" { - return nil - } - return ibchost.ConnectionIdentifierValidator(connId) -} diff --git a/x/ccv/provider/types/msg_test.go b/x/ccv/provider/types/msg_test.go index 149e291c70..39009c8316 100644 --- a/x/ccv/provider/types/msg_test.go +++ b/x/ccv/provider/types/msg_test.go @@ -742,46 +742,3 @@ func TestValidateInitialHeight(t *testing.T) { } } } - -func TestValidateConnectionIdentifier(t *testing.T) { - testCases := []struct { - name string - connId string - expPass bool - }{ - { - name: "valid connection ID", - connId: "connection-0", - expPass: true, - }, - { - name: "valid empty connection ID", - connId: "", - expPass: true, - }, - { - name: "invalid connection ID with /", - connId: "invalid-connection-id/", - expPass: false, - }, - { - name: "invalid connection ID with special characters", - connId: "connection-@#", - expPass: false, - }, - { - name: "invalid connection ID with spaces", - connId: "connection id", - expPass: false, - }, - } - - for _, tc := range testCases { - err := types.ValidateConnectionIdentifier(tc.connId) - if tc.expPass { - require.NoError(t, err, "valid case: '%s' should not return error. got %w", tc.name, err) - } else { - require.Error(t, err, "invalid case: '%s' must return error but got none", tc.name) - } - } -} diff --git a/x/ccv/provider/types/params.go b/x/ccv/provider/types/params.go index 2e144a5520..a278c81a73 100644 --- a/x/ccv/provider/types/params.go +++ b/x/ccv/provider/types/params.go @@ -99,21 +99,26 @@ func NewParams( } } +// DefaultTemplateClient is the default template client +func DefaultTemplateClient() *ibctmtypes.ClientState { + return ibctmtypes.NewClientState( + "", // chainID + ibctmtypes.DefaultTrustLevel, + 0, // trusting period + 0, // unbonding period + DefaultMaxClockDrift, + clienttypes.Height{}, // latest(initial) height + commitmenttypes.GetSDKSpecs(), + []string{"upgrade", "upgradedIBCState"}, + ) +} + // DefaultParams is the default params for the provider module func DefaultParams() Params { // create default client state with chainID, trusting period, unbonding period, and initial height zeroed out. // these fields will be populated during proposal handler. return NewParams( - ibctmtypes.NewClientState( - "", // chainID - ibctmtypes.DefaultTrustLevel, - 0, // trusting period - 0, // unbonding period - DefaultMaxClockDrift, - clienttypes.Height{}, // latest(initial) height - commitmenttypes.GetSDKSpecs(), - []string{"upgrade", "upgradedIBCState"}, - ), + DefaultTemplateClient(), DefaultTrustingPeriodFraction, ccvtypes.DefaultCCVTimeoutPeriod, DefaultSlashMeterReplenishPeriod, @@ -138,7 +143,7 @@ func (p Params) Validate() error { if err := ValidateTemplateClient(*p.TemplateClient); err != nil { return err } - if err := ccvtypes.ValidateStringFraction(p.TrustingPeriodFraction); err != nil { + if err := ccvtypes.ValidateStringFractionNonZero(p.TrustingPeriodFraction); err != nil { return fmt.Errorf("trusting period fraction is invalid: %s", err) } if err := ccvtypes.ValidateDuration(p.CcvTimeoutPeriod); err != nil { @@ -147,7 +152,7 @@ func (p Params) Validate() error { if err := ccvtypes.ValidateDuration(p.SlashMeterReplenishPeriod); err != nil { return fmt.Errorf("slash meter replenish period is invalid: %s", err) } - if err := ccvtypes.ValidateStringFraction(p.SlashMeterReplenishFraction); err != nil { + if err := ccvtypes.ValidateStringFractionNonZero(p.SlashMeterReplenishFraction); err != nil { return fmt.Errorf("slash meter replenish fraction is invalid: %s", err) } if err := ValidateCoin(p.ConsumerRewardDenomRegistrationFee); err != nil { diff --git a/x/ccv/types/genesis.go b/x/ccv/types/genesis.go index a7534b1289..632e6c2b7b 100644 --- a/x/ccv/types/genesis.go +++ b/x/ccv/types/genesis.go @@ -1,6 +1,8 @@ package types import ( + "strings" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" @@ -9,8 +11,13 @@ import ( ) // NewInitialConsumerGenesisState returns a ConsumerGenesisState for a completely new consumer chain. -func NewInitialConsumerGenesisState(cs *ibctmtypes.ClientState, consState *ibctmtypes.ConsensusState, - initValSet []abci.ValidatorUpdate, params ConsumerParams, +func NewInitialConsumerGenesisState( + cs *ibctmtypes.ClientState, + consState *ibctmtypes.ConsensusState, + initValSet []abci.ValidatorUpdate, + preCCV bool, + connectionId string, + params ConsumerParams, ) *ConsumerGenesisState { return &ConsumerGenesisState{ NewChain: true, @@ -20,6 +27,8 @@ func NewInitialConsumerGenesisState(cs *ibctmtypes.ClientState, consState *ibctm ConsensusState: consState, InitialValSet: initValSet, }, + PreCCV: preCCV, + ConnectionId: connectionId, } } @@ -41,8 +50,28 @@ func (gs ConsumerGenesisState) Validate() error { if err := gs.Params.Validate(); err != nil { return err } + if !gs.NewChain { + // consumer genesis should be for a new chain only + return errorsmod.Wrapf(ErrInvalidGenesis, "NewChain must be set to true") + } - if gs.NewChain { + if gs.PreCCV { + // consumer chain MUST start in pre-CCV state, i.e., + // the consumer CCV module MUST NOT pass validator updates + // to the underlying consensus engine + if gs.Provider.ClientState != nil || gs.Provider.ConsensusState != nil { + return errorsmod.Wrap(ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") + } + if err := ValidateConnectionIdentifier(gs.ConnectionId); err != nil { + return errorsmod.Wrapf(ErrInvalidGenesis, "ConnectionId: %s", err.Error()) + } + if strings.TrimSpace(gs.ConnectionId) == "" { + return errorsmod.Wrapf(ErrInvalidGenesis, "ConnectionId cannot be empty when preCCV is true") + } + } else { + // consumer chain MUST NOT start in pre-CCV state, i.e., + // the consumer CCV module MUST pass validator updates + // to the underlying consensus engine if gs.Provider.ClientState == nil { return errorsmod.Wrap(ErrInvalidGenesis, "provider client state cannot be nil for new chain") } @@ -55,8 +84,9 @@ func (gs ConsumerGenesisState) Validate() error { if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { return errorsmod.Wrapf(ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) } - } else if gs.Provider.ClientState != nil || gs.Provider.ConsensusState != nil { - return errorsmod.Wrap(ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") + if strings.TrimSpace(gs.ConnectionId) != "" { + return errorsmod.Wrapf(ErrInvalidGenesis, "ConnectionId must be empty when preCCV is false") + } } return nil } diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index abdf3d82bf..c6195c79f3 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -221,6 +221,13 @@ type ConsumerGenesisState struct { // This is needed and always set to true; otherwise, new_chain in the consumer // genesis state will default to false NewChain bool `protobuf:"varint,3,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` + // Flag indicating whether the consumer CCV module starts in pre-CCV state + PreCCV bool `protobuf:"varint,4,opt,name=preCCV,proto3" json:"preCCV,omitempty"` + // The ID of the connection end on the consumer chain on top of which the + // CCV channel will be established. If connection_id == "", a new client of + // the provider chain and a new connection on top of this client are created. + // The new client is initialized using client_state and consensus_state. + ConnectionId string `protobuf:"bytes,5,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` } func (m *ConsumerGenesisState) Reset() { *m = ConsumerGenesisState{} } @@ -277,6 +284,20 @@ func (m *ConsumerGenesisState) GetNewChain() bool { return false } +func (m *ConsumerGenesisState) GetPreCCV() bool { + if m != nil { + return m.PreCCV + } + return false +} + +func (m *ConsumerGenesisState) GetConnectionId() string { + if m != nil { + return m.ConnectionId + } + return "" +} + // ProviderInfo defines all information a consumer needs from a provider // Shared data type between provider and consumer type ProviderInfo struct { @@ -288,13 +309,6 @@ type ProviderInfo struct { ConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty"` // InitialValset filled in on new chain and on restart. InitialValSet []types.ValidatorUpdate `protobuf:"bytes,3,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` - // The ID of the connection end on the consumer chain on top of which the - // CCV channel will be established. If connection_id == "", a new client of - // the provider chain and a new connection on top of this client are created. - // The new client is initialized using client_state and consensus_state. - ConnectionId string `protobuf:"bytes,4,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` - // Flag indicating whether the consumer CCV module starts in pre-CCV state - PreCCV bool `protobuf:"varint,5,opt,name=preCCV,proto3" json:"preCCV,omitempty"` } func (m *ProviderInfo) Reset() { *m = ProviderInfo{} } @@ -351,20 +365,6 @@ func (m *ProviderInfo) GetInitialValSet() []types.ValidatorUpdate { return nil } -func (m *ProviderInfo) GetConnectionId() string { - if m != nil { - return m.ConnectionId - } - return "" -} - -func (m *ProviderInfo) GetPreCCV() bool { - if m != nil { - return m.PreCCV - } - return false -} - func init() { proto.RegisterType((*ConsumerParams)(nil), "interchain_security.ccv.v1.ConsumerParams") proto.RegisterType((*ConsumerGenesisState)(nil), "interchain_security.ccv.v1.ConsumerGenesisState") @@ -377,60 +377,60 @@ func init() { var fileDescriptor_d0a8be0efc64dfbc = []byte{ // 864 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x53, 0xe4, 0x44, - 0x14, 0x26, 0xcc, 0x0a, 0x43, 0xcf, 0x00, 0x6b, 0x8b, 0x18, 0xd9, 0xaa, 0x61, 0x16, 0x3d, 0x4c, - 0x69, 0x6d, 0x22, 0xb8, 0xa5, 0x55, 0xde, 0x64, 0x70, 0x5d, 0xf6, 0x00, 0xb3, 0x01, 0xb1, 0x4a, - 0x0f, 0x5d, 0x9d, 0xee, 0x37, 0x33, 0x5d, 0x66, 0xba, 0x53, 0xdd, 0x9d, 0x20, 0x77, 0x7f, 0x80, - 0x47, 0x7f, 0x90, 0x87, 0xf5, 0xb6, 0x47, 0x4f, 0x6a, 0xc1, 0x1f, 0xb1, 0xd2, 0x49, 0x86, 0x8c, - 0x25, 0xca, 0xde, 0xf2, 0x5e, 0x7f, 0xdf, 0x97, 0x7c, 0xef, 0xf5, 0x7b, 0x41, 0x9f, 0x08, 0x69, - 0x41, 0xb3, 0x29, 0x15, 0x92, 0x18, 0x60, 0x99, 0x16, 0xf6, 0x2a, 0x64, 0x2c, 0x0f, 0xf3, 0xfd, - 0xd0, 0x4c, 0xa9, 0x06, 0x4e, 0x98, 0x92, 0x26, 0x9b, 0x81, 0x0e, 0x52, 0xad, 0xac, 0xc2, 0x3b, - 0xff, 0xc2, 0x08, 0x18, 0xcb, 0x83, 0x7c, 0x7f, 0xe7, 0x91, 0x05, 0xc9, 0x41, 0xcf, 0x84, 0xb4, - 0x21, 0x8d, 0x99, 0x08, 0xed, 0x55, 0x0a, 0xa6, 0x24, 0xee, 0x84, 0x22, 0x66, 0x61, 0x22, 0x26, - 0x53, 0xcb, 0x12, 0x01, 0xd2, 0x9a, 0xb0, 0x81, 0xce, 0xf7, 0x1b, 0x51, 0x45, 0xe8, 0x4d, 0x94, - 0x9a, 0x24, 0x10, 0xba, 0x28, 0xce, 0xc6, 0x21, 0xcf, 0x34, 0xb5, 0x42, 0xc9, 0xea, 0x7c, 0x6b, - 0xa2, 0x26, 0xca, 0x3d, 0x86, 0xc5, 0x53, 0x99, 0xdd, 0xfb, 0x69, 0x15, 0x6d, 0x0c, 0xab, 0x4f, - 0x1e, 0x51, 0x4d, 0x67, 0x06, 0xfb, 0x68, 0x15, 0x24, 0x8d, 0x13, 0xe0, 0xbe, 0xd7, 0xf7, 0x06, - 0xed, 0xa8, 0x0e, 0xf1, 0x29, 0xfa, 0x30, 0x4e, 0x14, 0xfb, 0xc1, 0x90, 0x14, 0x34, 0xe1, 0xc2, - 0x58, 0x2d, 0xe2, 0xac, 0x78, 0x07, 0xb1, 0x9a, 0x4a, 0x33, 0x13, 0xc6, 0x08, 0x25, 0xfd, 0xe5, - 0xbe, 0x37, 0x68, 0x45, 0x8f, 0x4b, 0xec, 0x08, 0xf4, 0x51, 0x03, 0x79, 0xde, 0x00, 0xe2, 0x17, - 0xe8, 0xf1, 0x9d, 0x2a, 0x84, 0x4d, 0xa9, 0x94, 0x90, 0xf8, 0xad, 0xbe, 0x37, 0x58, 0x8b, 0x76, - 0xf9, 0x1d, 0x22, 0xc3, 0x12, 0x86, 0xbf, 0x40, 0x3b, 0xa9, 0x56, 0xb9, 0xe0, 0xa0, 0xc9, 0x18, - 0x80, 0xa4, 0x4a, 0x25, 0x84, 0x72, 0xae, 0x89, 0xb1, 0xda, 0x7f, 0xe0, 0x44, 0xb6, 0x6b, 0xc4, - 0x33, 0x80, 0x91, 0x52, 0xc9, 0x97, 0x9c, 0xeb, 0x33, 0xab, 0xf1, 0x4b, 0x84, 0x19, 0xcb, 0x89, - 0x15, 0x33, 0x50, 0x99, 0x2d, 0xdc, 0x09, 0xc5, 0xfd, 0xb7, 0xfa, 0xde, 0xa0, 0x73, 0xf0, 0x7e, - 0x50, 0x16, 0x36, 0xa8, 0x0b, 0x1b, 0x1c, 0x55, 0x85, 0x3d, 0x6c, 0xbf, 0xfa, 0x63, 0x77, 0xe9, - 0x97, 0x3f, 0x77, 0xbd, 0xe8, 0x21, 0x63, 0xf9, 0x79, 0xc9, 0x1e, 0x39, 0x32, 0xfe, 0x1e, 0xbd, - 0xe7, 0xdc, 0x8c, 0x41, 0xff, 0x53, 0x77, 0xe5, 0xfe, 0xba, 0xef, 0xd6, 0x1a, 0x8b, 0xe2, 0xcf, - 0x51, 0xbf, 0xbe, 0x67, 0x44, 0xc3, 0x42, 0x09, 0xc7, 0x9a, 0xb2, 0xe2, 0xc1, 0x5f, 0x75, 0x8e, - 0x7b, 0x35, 0x2e, 0x5a, 0x80, 0x3d, 0xab, 0x50, 0xf8, 0x09, 0xc2, 0x53, 0x61, 0xac, 0xd2, 0x82, - 0xd1, 0x84, 0x80, 0xb4, 0x5a, 0x80, 0xf1, 0xdb, 0xae, 0x81, 0x6f, 0xdf, 0x9e, 0x7c, 0x55, 0x1e, - 0xe0, 0x13, 0xf4, 0x30, 0x93, 0xb1, 0x92, 0x5c, 0xc8, 0x49, 0x6d, 0x67, 0xed, 0xfe, 0x76, 0x36, - 0xe7, 0xe4, 0xca, 0xc8, 0xe7, 0x68, 0xdb, 0xa8, 0xb1, 0x25, 0x2a, 0xb5, 0xa4, 0xa8, 0x90, 0x9d, - 0x6a, 0x30, 0x53, 0x95, 0x70, 0x1f, 0x15, 0x9f, 0x7f, 0xb8, 0xec, 0x7b, 0xd1, 0x3b, 0x05, 0xe2, - 0x34, 0xb5, 0xa7, 0x99, 0x3d, 0xaf, 0x8f, 0xf1, 0x07, 0x68, 0x5d, 0xc3, 0x25, 0xd5, 0x9c, 0x70, - 0x90, 0x6a, 0x66, 0xfc, 0x4e, 0xbf, 0x35, 0x58, 0x8b, 0xba, 0x65, 0xf2, 0xc8, 0xe5, 0xf0, 0x53, - 0x34, 0x6f, 0x38, 0x59, 0x44, 0x77, 0x1d, 0x7a, 0xab, 0x3e, 0x8d, 0x9a, 0xac, 0x97, 0x08, 0x6b, - 0xb0, 0xfa, 0x8a, 0x70, 0x48, 0xe8, 0x55, 0xed, 0x72, 0xfd, 0x0d, 0x2e, 0x83, 0xa3, 0x1f, 0x15, - 0xec, 0xca, 0xe6, 0x2e, 0xea, 0xcc, 0xfb, 0x25, 0xb8, 0xbf, 0xe1, 0x5a, 0x83, 0xea, 0xd4, 0x31, - 0xdf, 0xfb, 0xcd, 0x43, 0x5b, 0xf5, 0x18, 0x7e, 0x0d, 0x12, 0x8c, 0x30, 0x67, 0x96, 0x5a, 0xc0, - 0xcf, 0xd1, 0x4a, 0xea, 0xc6, 0xd2, 0xcd, 0x62, 0xe7, 0xe0, 0xa3, 0xe0, 0xee, 0x85, 0x12, 0x2c, - 0x0e, 0xf2, 0xe1, 0x83, 0xe2, 0x8b, 0xa2, 0x8a, 0x8f, 0x5f, 0xa0, 0x76, 0x6d, 0xd7, 0x0d, 0x68, - 0xe7, 0x60, 0xf0, 0x5f, 0x5a, 0xa3, 0x0a, 0x7b, 0x2c, 0xc7, 0xaa, 0x52, 0x9a, 0xf3, 0xf1, 0x23, - 0xb4, 0x26, 0xe1, 0x92, 0x38, 0xa6, 0x9b, 0xcf, 0x76, 0xd4, 0x96, 0x70, 0x39, 0x2c, 0xe2, 0xbd, - 0x5f, 0x97, 0x51, 0xb7, 0xc9, 0xc6, 0x27, 0xa8, 0x5b, 0xee, 0x30, 0x62, 0x0a, 0x4f, 0x95, 0x93, - 0x8f, 0x03, 0x11, 0xb3, 0xa0, 0xb9, 0xe1, 0x82, 0xc6, 0x4e, 0x2b, 0xdc, 0xb8, 0xac, 0x2b, 0x43, - 0xd4, 0x61, 0xb7, 0x01, 0xfe, 0x16, 0x6d, 0x16, 0xa5, 0x03, 0x69, 0x32, 0x53, 0x49, 0x96, 0x86, - 0x82, 0xff, 0x95, 0xac, 0x69, 0xa5, 0xea, 0x06, 0x5b, 0x88, 0xf1, 0x09, 0xda, 0x14, 0x52, 0x58, - 0x41, 0x13, 0x92, 0xd3, 0x84, 0x18, 0xb0, 0x7e, 0xab, 0xdf, 0x1a, 0x74, 0x0e, 0xfa, 0x4d, 0x9d, - 0x62, 0x55, 0x07, 0x17, 0x34, 0x11, 0x9c, 0x5a, 0xa5, 0xbf, 0x49, 0x39, 0xb5, 0x50, 0x55, 0x68, - 0xbd, 0xa2, 0x5f, 0xd0, 0xe4, 0x0c, 0x6c, 0x71, 0x49, 0x99, 0x92, 0x12, 0xdc, 0xa8, 0x15, 0x8d, - 0x2f, 0xb7, 0x50, 0xf7, 0x36, 0x79, 0xcc, 0xf1, 0x36, 0x5a, 0x49, 0x35, 0x0c, 0x87, 0x17, 0x6e, - 0xdf, 0xb4, 0xa3, 0x2a, 0x3a, 0x3c, 0x79, 0x75, 0xdd, 0xf3, 0x5e, 0x5f, 0xf7, 0xbc, 0xbf, 0xae, - 0x7b, 0xde, 0xcf, 0x37, 0xbd, 0xa5, 0xd7, 0x37, 0xbd, 0xa5, 0xdf, 0x6f, 0x7a, 0x4b, 0xdf, 0x3d, - 0x9d, 0x08, 0x3b, 0xcd, 0xe2, 0x80, 0xa9, 0x59, 0xc8, 0x94, 0x99, 0x29, 0x13, 0xde, 0x36, 0xf2, - 0xc9, 0xfc, 0xbf, 0x94, 0x7f, 0x16, 0xfe, 0xe8, 0x7e, 0x4e, 0xee, 0xb7, 0x12, 0xaf, 0xb8, 0x2b, - 0xfb, 0xe9, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x64, 0xc8, 0x7f, 0xef, 0xc4, 0x06, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x6f, 0xe4, 0x34, + 0x14, 0x6e, 0x3a, 0xbb, 0xed, 0xd4, 0x33, 0x6d, 0x17, 0x53, 0x4a, 0xe8, 0x4a, 0xd3, 0xd9, 0xc2, + 0x61, 0x04, 0xda, 0x84, 0x96, 0x15, 0x48, 0xdc, 0xe8, 0x94, 0x65, 0xbb, 0x87, 0x76, 0x36, 0x2d, + 0x45, 0x82, 0x83, 0xe5, 0xd8, 0x6f, 0x66, 0x2c, 0x32, 0x76, 0x64, 0x3b, 0x29, 0xbd, 0x23, 0xb8, + 0x72, 0xe4, 0x27, 0xed, 0x71, 0x8f, 0x9c, 0x00, 0xb5, 0x7f, 0x04, 0xc5, 0x49, 0xa6, 0x19, 0x44, + 0xa1, 0xdc, 0xf2, 0x9e, 0xbf, 0xef, 0x8b, 0xdf, 0xf7, 0xfc, 0x6c, 0xf4, 0xb1, 0x90, 0x16, 0x34, + 0x9b, 0x52, 0x21, 0x89, 0x01, 0x96, 0x69, 0x61, 0xaf, 0x42, 0xc6, 0xf2, 0x30, 0xdf, 0x0f, 0xcd, + 0x94, 0x6a, 0xe0, 0x84, 0x29, 0x69, 0xb2, 0x19, 0xe8, 0x20, 0xd5, 0xca, 0x2a, 0xbc, 0xf3, 0x0f, + 0x8c, 0x80, 0xb1, 0x3c, 0xc8, 0xf7, 0x77, 0x1e, 0x5b, 0x90, 0x1c, 0xf4, 0x4c, 0x48, 0x1b, 0xd2, + 0x98, 0x89, 0xd0, 0x5e, 0xa5, 0x60, 0x4a, 0xe2, 0x4e, 0x28, 0x62, 0x16, 0x26, 0x62, 0x32, 0xb5, + 0x2c, 0x11, 0x20, 0xad, 0x09, 0x1b, 0xe8, 0x7c, 0xbf, 0x11, 0x55, 0x84, 0xde, 0x44, 0xa9, 0x49, + 0x02, 0xa1, 0x8b, 0xe2, 0x6c, 0x1c, 0xf2, 0x4c, 0x53, 0x2b, 0x94, 0xac, 0xd6, 0xb7, 0x26, 0x6a, + 0xa2, 0xdc, 0x67, 0x58, 0x7c, 0x95, 0xd9, 0xbd, 0x1f, 0x57, 0xd1, 0xc6, 0xb0, 0xda, 0xf2, 0x88, + 0x6a, 0x3a, 0x33, 0xd8, 0x47, 0xab, 0x20, 0x69, 0x9c, 0x00, 0xf7, 0xbd, 0xbe, 0x37, 0x68, 0x47, + 0x75, 0x88, 0x4f, 0xd1, 0x07, 0x71, 0xa2, 0xd8, 0xf7, 0x86, 0xa4, 0xa0, 0x09, 0x17, 0xc6, 0x6a, + 0x11, 0x67, 0xc5, 0x3f, 0x88, 0xd5, 0x54, 0x9a, 0x99, 0x30, 0x46, 0x28, 0xe9, 0x2f, 0xf7, 0xbd, + 0x41, 0x2b, 0x7a, 0x52, 0x62, 0x47, 0xa0, 0x8f, 0x1a, 0xc8, 0xf3, 0x06, 0x10, 0xbf, 0x44, 0x4f, + 0xee, 0x54, 0x21, 0x6c, 0x4a, 0xa5, 0x84, 0xc4, 0x6f, 0xf5, 0xbd, 0xc1, 0x5a, 0xb4, 0xcb, 0xef, + 0x10, 0x19, 0x96, 0x30, 0xfc, 0x39, 0xda, 0x49, 0xb5, 0xca, 0x05, 0x07, 0x4d, 0xc6, 0x00, 0x24, + 0x55, 0x2a, 0x21, 0x94, 0x73, 0x4d, 0x8c, 0xd5, 0xfe, 0x03, 0x27, 0xb2, 0x5d, 0x23, 0x9e, 0x03, + 0x8c, 0x94, 0x4a, 0xbe, 0xe0, 0x5c, 0x9f, 0x59, 0x8d, 0x5f, 0x21, 0xcc, 0x58, 0x4e, 0xac, 0x98, + 0x81, 0xca, 0x6c, 0x51, 0x9d, 0x50, 0xdc, 0x7f, 0xd8, 0xf7, 0x06, 0x9d, 0x83, 0xf7, 0x82, 0xd2, + 0xd8, 0xa0, 0x36, 0x36, 0x38, 0xaa, 0x8c, 0x3d, 0x6c, 0xbf, 0xfe, 0x7d, 0x77, 0xe9, 0xd7, 0x3f, + 0x76, 0xbd, 0xe8, 0x11, 0x63, 0xf9, 0x79, 0xc9, 0x1e, 0x39, 0x32, 0xfe, 0x0e, 0xbd, 0xeb, 0xaa, + 0x19, 0x83, 0xfe, 0xbb, 0xee, 0xca, 0xfd, 0x75, 0xdf, 0xa9, 0x35, 0x16, 0xc5, 0x5f, 0xa0, 0x7e, + 0x7d, 0xce, 0x88, 0x86, 0x05, 0x0b, 0xc7, 0x9a, 0xb2, 0xe2, 0xc3, 0x5f, 0x75, 0x15, 0xf7, 0x6a, + 0x5c, 0xb4, 0x00, 0x7b, 0x5e, 0xa1, 0xf0, 0x53, 0x84, 0xa7, 0xc2, 0x58, 0xa5, 0x05, 0xa3, 0x09, + 0x01, 0x69, 0xb5, 0x00, 0xe3, 0xb7, 0x5d, 0x03, 0xdf, 0xba, 0x5d, 0xf9, 0xb2, 0x5c, 0xc0, 0x27, + 0xe8, 0x51, 0x26, 0x63, 0x25, 0xb9, 0x90, 0x93, 0xba, 0x9c, 0xb5, 0xfb, 0x97, 0xb3, 0x39, 0x27, + 0x57, 0x85, 0x7c, 0x86, 0xb6, 0x8d, 0x1a, 0x5b, 0xa2, 0x52, 0x4b, 0x0a, 0x87, 0xec, 0x54, 0x83, + 0x99, 0xaa, 0x84, 0xfb, 0xa8, 0xd8, 0xfe, 0xe1, 0xb2, 0xef, 0x45, 0x6f, 0x17, 0x88, 0xd3, 0xd4, + 0x9e, 0x66, 0xf6, 0xbc, 0x5e, 0xc6, 0xef, 0xa3, 0x75, 0x0d, 0x97, 0x54, 0x73, 0xc2, 0x41, 0xaa, + 0x99, 0xf1, 0x3b, 0xfd, 0xd6, 0x60, 0x2d, 0xea, 0x96, 0xc9, 0x23, 0x97, 0xc3, 0xcf, 0xd0, 0xbc, + 0xe1, 0x64, 0x11, 0xdd, 0x75, 0xe8, 0xad, 0x7a, 0x35, 0x6a, 0xb2, 0x5e, 0x21, 0xac, 0xc1, 0xea, + 0x2b, 0xc2, 0x21, 0xa1, 0x57, 0x75, 0x95, 0xeb, 0xff, 0xe3, 0x30, 0x38, 0xfa, 0x51, 0xc1, 0xae, + 0xca, 0xdc, 0x45, 0x9d, 0x79, 0xbf, 0x04, 0xf7, 0x37, 0x5c, 0x6b, 0x50, 0x9d, 0x3a, 0xe6, 0x7b, + 0x3f, 0x2d, 0xa3, 0xad, 0x7a, 0x0c, 0xbf, 0x02, 0x09, 0x46, 0x98, 0x33, 0x4b, 0x2d, 0xe0, 0x17, + 0x68, 0x25, 0x75, 0x63, 0xe9, 0x66, 0xb1, 0x73, 0xf0, 0x61, 0x70, 0xf7, 0x85, 0x12, 0x2c, 0x0e, + 0xf2, 0xe1, 0x83, 0x62, 0x47, 0x51, 0xc5, 0xc7, 0x2f, 0x51, 0xbb, 0x2e, 0xd7, 0x0d, 0x68, 0xe7, + 0x60, 0xf0, 0x6f, 0x5a, 0xa3, 0x0a, 0x7b, 0x2c, 0xc7, 0xaa, 0x52, 0x9a, 0xf3, 0xf1, 0x63, 0xb4, + 0x26, 0xe1, 0x92, 0x38, 0xa6, 0x9b, 0xcf, 0x76, 0xd4, 0x96, 0x70, 0x39, 0x2c, 0x62, 0xbc, 0x8d, + 0x56, 0x52, 0x0d, 0xc3, 0xe1, 0x85, 0x1b, 0xba, 0x76, 0x54, 0x45, 0x45, 0xcb, 0x98, 0x92, 0x12, + 0xdc, 0xc1, 0x2b, 0x6c, 0x78, 0xe8, 0x6c, 0xe8, 0xde, 0x26, 0x8f, 0xf9, 0xde, 0xcf, 0xcb, 0xa8, + 0xdb, 0xfc, 0x35, 0x3e, 0x41, 0xdd, 0xf2, 0x02, 0x24, 0xa6, 0x30, 0xa4, 0xb2, 0xe1, 0xa3, 0x40, + 0xc4, 0x2c, 0x68, 0x5e, 0x8f, 0x41, 0xe3, 0x42, 0x2c, 0xac, 0x70, 0x59, 0xe7, 0x61, 0xd4, 0x61, + 0xb7, 0x01, 0xfe, 0x06, 0x6d, 0x16, 0xbe, 0x83, 0x34, 0x99, 0xa9, 0x24, 0x4b, 0x37, 0x82, 0xff, + 0x94, 0xac, 0x69, 0xa5, 0xea, 0x06, 0x5b, 0x88, 0xf1, 0x09, 0xda, 0x14, 0x52, 0x58, 0x41, 0x13, + 0x92, 0xd3, 0x84, 0x18, 0xb0, 0x7e, 0xab, 0xdf, 0x1a, 0x74, 0x0e, 0xfa, 0x4d, 0x9d, 0xe2, 0x9e, + 0x0f, 0x2e, 0x68, 0x22, 0x38, 0xb5, 0x4a, 0x7f, 0x9d, 0x72, 0x6a, 0xa1, 0xb2, 0x77, 0xbd, 0xa2, + 0x5f, 0xd0, 0xe4, 0x0c, 0xec, 0xe1, 0xc9, 0xeb, 0xeb, 0x9e, 0xf7, 0xe6, 0xba, 0xe7, 0xfd, 0x79, + 0xdd, 0xf3, 0x7e, 0xb9, 0xe9, 0x2d, 0xbd, 0xb9, 0xe9, 0x2d, 0xfd, 0x76, 0xd3, 0x5b, 0xfa, 0xf6, + 0xd9, 0x44, 0xd8, 0x69, 0x16, 0x07, 0x4c, 0xcd, 0x42, 0xa6, 0xcc, 0x4c, 0x99, 0xf0, 0xb6, 0x91, + 0x4f, 0xe7, 0xef, 0x52, 0xfe, 0x69, 0xf8, 0x83, 0x7b, 0x9c, 0xdc, 0xb3, 0x12, 0xaf, 0xb8, 0x23, + 0xfb, 0xc9, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xc1, 0x9c, 0xfa, 0xc4, 0x06, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { @@ -581,6 +581,23 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x2a + } + if m.PreCCV { + i-- + if m.PreCCV { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } if m.NewChain { i-- if m.NewChain { @@ -634,23 +651,6 @@ func (m *ProviderInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.PreCCV { - i-- - if m.PreCCV { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x28 - } - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x22 - } if len(m.InitialValSet) > 0 { for iNdEx := len(m.InitialValSet) - 1; iNdEx >= 0; iNdEx-- { { @@ -774,6 +774,13 @@ func (m *ConsumerGenesisState) Size() (n int) { if m.NewChain { n += 2 } + if m.PreCCV { + n += 2 + } + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovSharedConsumer(uint64(l)) + } return n } @@ -797,13 +804,6 @@ func (m *ProviderInfo) Size() (n int) { n += 1 + l + sovSharedConsumer(uint64(l)) } } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovSharedConsumer(uint64(l)) - } - if m.PreCCV { - n += 2 - } return n } @@ -1392,6 +1392,58 @@ func (m *ConsumerGenesisState) Unmarshal(dAtA []byte) error { } } m.NewChain = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSharedConsumer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PreCCV = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSharedConsumer + } + 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 ErrInvalidLengthSharedConsumer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSharedConsumer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSharedConsumer(dAtA[iNdEx:]) @@ -1548,58 +1600,6 @@ func (m *ProviderInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - 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 ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.PreCCV = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSharedConsumer(dAtA[iNdEx:]) diff --git a/x/ccv/types/shared_params.go b/x/ccv/types/shared_params.go index aa90134f3f..75488bf590 100644 --- a/x/ccv/types/shared_params.go +++ b/x/ccv/types/shared_params.go @@ -81,6 +81,14 @@ func ValidateChannelIdentifier(i interface{}) error { return ibchost.ChannelIdentifierValidator(value) } +func ValidateConnectionIdentifier(connId string) error { + // accept empty string as valid + if strings.TrimSpace(connId) == "" { + return nil + } + return ibchost.ConnectionIdentifierValidator(connId) +} + func ValidateAccAddress(i interface{}) error { value, ok := i.(string) if !ok { @@ -108,6 +116,19 @@ func ValidateStringFraction(i interface{}) error { return nil } +func ValidateStringFractionNonZero(i interface{}) error { + if err := ValidateStringFraction(i); err != nil { + return err + } + str, _ := i.(string) + dec, _ := math.LegacyNewDecFromStr(str) + if dec.IsZero() { + return fmt.Errorf("param cannot be zero, got %s", str) + } + + return nil +} + func CalculateTrustPeriod(unbondingPeriod time.Duration, defaultTrustPeriodFraction string) (time.Duration, error) { trustDec, err := math.LegacyNewDecFromStr(defaultTrustPeriodFraction) if err != nil { diff --git a/x/ccv/types/shared_params_test.go b/x/ccv/types/shared_params_test.go index 9d2bbfce00..0b38f3f839 100644 --- a/x/ccv/types/shared_params_test.go +++ b/x/ccv/types/shared_params_test.go @@ -21,3 +21,51 @@ func TestValidateConsumerId(t *testing.T) { require.NoError(t, types.ValidateConsumerId("0")) require.NoError(t, types.ValidateConsumerId("18446744073709551615")) // 2^64 - 1 } + +func TestValidateConnectionIdentifier(t *testing.T) { + testCases := []struct { + name string + connId string + expPass bool + }{ + { + name: "valid connection ID", + connId: "connection-0", + expPass: true, + }, + { + name: "valid empty connection ID", + connId: "", + expPass: true, + }, + { + name: "valid empty (multiple spaces) connection ID", + connId: " ", + expPass: true, + }, + { + name: "invalid connection ID with /", + connId: "invalid-connection-id/", + expPass: false, + }, + { + name: "invalid connection ID with special characters", + connId: "connection-@#", + expPass: false, + }, + { + name: "invalid connection ID with spaces", + connId: "connection id", + expPass: false, + }, + } + + for _, tc := range testCases { + err := types.ValidateConnectionIdentifier(tc.connId) + if tc.expPass { + require.NoError(t, err, "valid case: '%s' should not return error. got %w", tc.name, err) + } else { + require.Error(t, err, "invalid case: '%s' must return error but got none", tc.name) + } + } +} From 049dd9e4b40745cd7bc5a8a77cae5c1d86df4b0c Mon Sep 17 00:00:00 2001 From: mpoke Date: Mon, 11 Nov 2024 17:23:46 +0100 Subject: [PATCH 05/25] add provider logic for non-empty connId --- x/ccv/provider/keeper/consumer_lifecycle.go | 58 +++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/x/ccv/provider/keeper/consumer_lifecycle.go b/x/ccv/provider/keeper/consumer_lifecycle.go index abfbf2351e..a6fb6193ae 100644 --- a/x/ccv/provider/keeper/consumer_lifecycle.go +++ b/x/ccv/provider/keeper/consumer_lifecycle.go @@ -5,8 +5,10 @@ import ( "time" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" @@ -254,6 +256,11 @@ func (k Keeper) CreateConsumerClient( if err != nil { return err } + if initializationRecord.ConnectionId != "" { + // there is no need to create a client if the connection ID is provided + // as the CCV channel will be built on top of the existing client + return nil + } phase := k.GetConsumerPhase(ctx, consumerId) if phase != types.CONSUMER_PHASE_INITIALIZED { @@ -389,9 +396,54 @@ func (k Keeper) MakeConsumerGenesis( } else { // connection ID provided preCCV = true - // TODO - // check validity - // connectionEnd.counterpartyConnectionIdentifier, + + // get the connection end + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, initializationRecord.ConnectionId) + if !found { + return gen, errorsmod.Wrapf(conntypes.ErrConnectionNotFound, + "could not find connection(%s)", initializationRecord.ConnectionId) + } + clientId := connectionEnd.ClientId + + // check that the underlying client is a Tendermint client and that the chain ID matches + clientState, found := k.clientKeeper.GetClientState(ctx, clientId) + if !found { + return gen, errorsmod.Wrapf(clienttypes.ErrClientNotFound, + "could not find client(%s) associated with connection(%s)", + clientId, initializationRecord.ConnectionId, + ) + } + tmClient, ok := clientState.(*ibctmtypes.ClientState) + if !ok { + return gen, errorsmod.Wrapf(clienttypes.ErrInvalidClientType, + "invalid client type. expected %s, got %s", + ibchost.Tendermint, clientState.ClientType(), + ) + } + consumerChainId, err := k.GetConsumerChainId(ctx, consumerId) + if err != nil { + return gen, err + } + if tmClient.ChainId != consumerChainId { + return gen, errorsmod.Wrapf(conntypes.ErrInvalidConnectionIdentifier, + "invalid connection(%s): expected chain ID %s, got %s", + initializationRecord.ConnectionId, consumerChainId, tmClient.ChainId, + ) + } + + // set the counterparty connection ID + counterpartyConnectionId = connectionEnd.Counterparty.ConnectionId + + k.SetConsumerClientId(ctx, consumerId, clientId) + + // Set minimum height for equivocation evidence from this consumer chain + k.SetEquivocationEvidenceMinHeight(ctx, consumerId, tmClient.LatestHeight.RevisionHeight) + + k.Logger(ctx).Info("use existing client and connection for consumer chain", + "consumer id", consumerId, + "client id", clientId, + "connection id", initializationRecord.ConnectionId, + ) } gen = *ccv.NewInitialConsumerGenesisState( From fa189f582105c14a7bc54cd904cb41dcb772a646 Mon Sep 17 00:00:00 2001 From: mpoke Date: Wed, 13 Nov 2024 11:24:15 +0100 Subject: [PATCH 06/25] validate consumer genesis --- go.mod | 2 +- x/ccv/consumer/keeper/genesis.go | 32 +++++++++-- x/ccv/consumer/types/genesis.go | 57 +++++++++++++------ x/ccv/consumer/types/genesis_test.go | 84 ++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 925bbbeea9..37bb911a96 100644 --- a/go.mod +++ b/go.mod @@ -145,7 +145,6 @@ require ( require ( cosmossdk.io/client/v2 v2.0.0-beta.3 - cosmossdk.io/collections v0.4.0 cosmossdk.io/log v1.4.1 cosmossdk.io/store v1.1.0 cosmossdk.io/tools/confix v0.1.2 @@ -165,6 +164,7 @@ require ( require ( cloud.google.com/go/auth v0.6.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect + cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/x/circuit v0.1.1 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index 5e850ba351..24c282bf17 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -3,7 +3,9 @@ package keeper import ( "fmt" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" abci "github.com/cometbft/cometbft/abci/types" @@ -55,11 +57,31 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V // initialValSet is checked in NewChain case by ValidateGenesis // start a new chain if state.NewChain { - // create the provider client in InitGenesis for new consumer chain. CCV Handshake must be established with this client id. - clientID, err := k.clientKeeper.CreateClient(ctx, state.Provider.ClientState, state.Provider.ConsensusState) - if err != nil { - // If the client creation fails, the chain MUST NOT start - panic(err) + var clientID string + if state.ConnectionId == "" { + // create the provider client in InitGenesis for new consumer chain. CCV Handshake must be established with this client id. + cid, err := k.clientKeeper.CreateClient(ctx, state.Provider.ClientState, state.Provider.ConsensusState) + if err != nil { + // If the client creation fails, the chain MUST NOT start + panic(err) + } + clientID = cid + + k.Logger(ctx).Info("create new provider chain client", + "client id", clientID, + ) + } else { + // if connection id is provided, then the client is already created + connectionEnd, found := k.connectionKeeper.GetConnection(ctx, state.ConnectionId) + if !found { + panic(errorsmod.Wrapf(conntypes.ErrConnectionNotFound, "could not find connection(%s)", state.ConnectionId)) + } + clientID = connectionEnd.ClientId + + k.Logger(ctx).Info("use existing client and connection to provider chain", + "client id", clientID, + "connection id", state.ConnectionId, + ) } // set provider client id. diff --git a/x/ccv/consumer/types/genesis.go b/x/ccv/consumer/types/genesis.go index 2d5ae3a848..907756b9ca 100644 --- a/x/ccv/consumer/types/genesis.go +++ b/x/ccv/consumer/types/genesis.go @@ -64,7 +64,13 @@ func NewInitialGenesisState(cs *ibctmtypes.ClientState, consState *ibctmtypes.Co // expect the following optional and mandatory genesis states: // // 1. New chain starts: -// - Params, InitialValset, provider client state, provider consensus state // mandatory +// - Params, InitialValset // mandatory +// +// 1a. ConnectionId is empty +// - provider client state, provider consensus state // mandatory +// +// 1b. ConnectionId is not empty +// - provider client state, provider consensus state // nil // // 2. Chain restarts with CCV handshake still in progress: // - Params, InitialValset, ProviderID, HeightToValidatorSetUpdateID // mandatory @@ -73,8 +79,6 @@ func NewInitialGenesisState(cs *ibctmtypes.ClientState, consState *ibctmtypes.Co // 3. Chain restarts with CCV handshake completed: // - Params, InitialValset, ProviderID, channelID, HeightToValidatorSetUpdateID // mandatory // - MaturingVSCPackets, OutstandingDowntime, PendingConsumerPacket, LastTransmissionBlockHeight // optional -// - func (gs GenesisState) Validate() error { if !gs.Params.Enabled { return nil @@ -87,24 +91,45 @@ func (gs GenesisState) Validate() error { } if gs.NewChain { - if gs.Provider.ClientState == nil { - return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state cannot be nil for new chain") - } - if err := gs.Provider.ClientState.Validate(); err != nil { - return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) - } - if gs.Provider.ConsensusState == nil { - return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") - } - if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { - return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) + if gs.ConnectionId == "" { + // connection ID is not provided + if gs.Provider.ClientState == nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state cannot be nil for new chain") + } + if err := gs.Provider.ClientState.Validate(); err != nil { + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) + } + if gs.Provider.ConsensusState == nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") + } + if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) + } + } else { + // connection ID is provided + if gs.Provider.ClientState != nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state must be nil when connection id is provided") + } + if gs.Provider.ConsensusState != nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider consensus state must be nil when connection id is provided") + } + if err := ccv.ValidateConnectionIdentifier(gs.ConnectionId); err != nil { + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "invalid connection id: %s", err.Error()) + } } + if gs.ProviderClientId != "" { return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake") } if gs.ProviderChannelId != "" { return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake") } + if len(gs.HeightToValsetUpdateId) != 0 { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "HeightToValsetUpdateId must be nil for new chain") + } + if len(gs.OutstandingDowntimeSlashing) != 0 { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "OutstandingDowntimeSlashing must be nil for new chain") + } if len(gs.PendingConsumerPackets.List) != 0 { return errorsmod.Wrap(ccv.ErrInvalidGenesis, "pending consumer packets must be empty for new chain") } @@ -121,11 +146,11 @@ func (gs GenesisState) Validate() error { if handshakeInProgress { if len(gs.OutstandingDowntimeSlashing) != 0 { return errorsmod.Wrap( - ccv.ErrInvalidGenesis, "outstanding downtime must be empty when handshake isn't completed") + ccv.ErrInvalidGenesis, "outstanding downtime must be empty when handshake in progress") } if gs.LastTransmissionBlockHeight.Height != 0 { return errorsmod.Wrap( - ccv.ErrInvalidGenesis, "last transmission block height must be zero when handshake isn't completed") + ccv.ErrInvalidGenesis, "last transmission block height must be zero when handshake in progress") } if len(gs.PendingConsumerPackets.List) != 0 { for _, packet := range gs.PendingConsumerPackets.List { diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index bbe031d0d7..8faa41c3a7 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -231,6 +231,90 @@ func TestValidateInitialGenesisState(t *testing.T) { )), true, }, + { + "invalid new consumer genesis state: connection id is invalid", + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: nil, + ConsensusState: nil, + InitialValSet: valUpdates, + }, + HeightToValsetUpdateId: nil, + OutstandingDowntimeSlashing: nil, + PendingConsumerPackets: types.ConsumerPacketDataList{}, + LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, + ConnectionId: "invalid_connection/", + }, + true, + }, + { + "invalid new consumer genesis state: client state provided with connection id", + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: nil, + InitialValSet: valUpdates, + }, + HeightToValsetUpdateId: nil, + OutstandingDowntimeSlashing: nil, + PendingConsumerPackets: types.ConsumerPacketDataList{}, + LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, + ConnectionId: "connection-1", + }, + true, + }, + { + "invalid new consumer genesis state: client state provided with connection id", + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: nil, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, + HeightToValsetUpdateId: nil, + OutstandingDowntimeSlashing: nil, + PendingConsumerPackets: types.ConsumerPacketDataList{}, + LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, + ConnectionId: "connection-1", + }, + true, + }, + { + "valid new consumer genesis state: connection id", + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: nil, + ConsensusState: nil, + InitialValSet: valUpdates, + }, + HeightToValsetUpdateId: nil, + OutstandingDowntimeSlashing: nil, + PendingConsumerPackets: types.ConsumerPacketDataList{}, + LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, + PreCCV: false, + ConnectionId: "connection-1", + }, + false, + }, } for _, c := range cases { From 81536d8d5170fa2a6cf4d6ace452c3040416e6be Mon Sep 17 00:00:00 2001 From: mpoke Date: Wed, 13 Nov 2024 12:41:46 +0100 Subject: [PATCH 07/25] initiate CCV channel handshake --- x/ccv/consumer/keeper/genesis.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index 24c282bf17..74bc631724 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -6,6 +6,7 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" abci "github.com/cometbft/cometbft/abci/types" @@ -90,6 +91,26 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V // set default value for valset update ID k.SetHeightValsetUpdateID(ctx, uint64(ctx.BlockHeight()), uint64(0)) + if state.ConnectionId != "" { + // initiate CCV channel handshake + ccvChannelOpenInitMsg := channeltypes.NewMsgChannelOpenInit( + ccv.ConsumerPortID, + ccv.Version, + channeltypes.ORDERED, + []string{state.ConnectionId}, + ccv.ProviderPortID, + "", // signer unused + ) + _, err := k.ChannelOpenInit(ctx, ccvChannelOpenInitMsg) + if err != nil { + panic(err) + } + + // Note that if the connection ID is not provider, we cannot initiate + // the connection handshake as the counterparty client ID is unknown + // at this point. The connection handshake must be initiated by a relayer. + } + } else { // chain restarts with the CCV channel established if state.ProviderChannelId != "" { From b07b3abf8e7f90d3d9f0975ffd1847ee3fa8b1ca Mon Sep 17 00:00:00 2001 From: mpoke Date: Wed, 13 Nov 2024 13:10:00 +0100 Subject: [PATCH 08/25] fix UT --- x/ccv/provider/types/params_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/ccv/provider/types/params_test.go b/x/ccv/provider/types/params_test.go index 29ece2f2c3..b323d31f26 100644 --- a/x/ccv/provider/types/params_test.go +++ b/x/ccv/provider/types/params_test.go @@ -34,10 +34,9 @@ func TestValidateParams(t *testing.T) { {"blank client", types.NewParams(&ibctmtypes.ClientState{}, "0.33", time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24, 180), false}, {"nil client", types.NewParams(nil, "0.33", time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24, 180), false}, - // Check if "0.00" is valid or if a zero dec TrustFraction needs to return an error {"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.00", time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24, 180), true}, + "0.00", time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24, 180), false}, {"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), "0.33", 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24, 180), false}, From 940596d9a54ec449ec5124dacd697017fb3b9c8c Mon Sep 17 00:00:00 2001 From: mpoke Date: Wed, 13 Nov 2024 13:42:44 +0100 Subject: [PATCH 09/25] add changelog entries --- .changelog/unreleased/api-breaking/2400-preccv.md | 12 ++++++++++++ .changelog/unreleased/features/2400-preccv.md | 13 +++++++++++++ .changelog/unreleased/state-breaking/2400-preccv.md | 3 +++ docs/docs/build/modules/02-provider.md | 4 +++- x/ccv/provider/client/cli/tx.go | 6 ++++-- 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 .changelog/unreleased/api-breaking/2400-preccv.md create mode 100644 .changelog/unreleased/features/2400-preccv.md create mode 100644 .changelog/unreleased/state-breaking/2400-preccv.md diff --git a/.changelog/unreleased/api-breaking/2400-preccv.md b/.changelog/unreleased/api-breaking/2400-preccv.md new file mode 100644 index 0000000000..2714f1e522 --- /dev/null +++ b/.changelog/unreleased/api-breaking/2400-preccv.md @@ -0,0 +1,12 @@ +- Enable existing (standalone) chains to use the existing client (and connection) + to the provider chain when becoming a consumer chain. This feature introduces + the following API-breaking changes. + ([\#2400](https://github.com/cosmos/interchain-security/pull/2400)) + + - Add `connection_id` and `preCCV` to `ConsumerGenesisState`, the consumer + genesis state created by the provider chain. If the `connection_id` is not empty, + `preCCV` is set to true and both `provider.client_state` and `provider.consensus_state` + are set to nil (as the consumer doesn't need to create a new provider client). + As a result, for older versions of consumers, the `connection_id` in + `ConsumerInitializationParameters` must be empty and the resulting `ConsumerGenesisState` + needs to be adapted, i.e., both `connection_id` and `preCCV` need to be removed. \ No newline at end of file diff --git a/.changelog/unreleased/features/2400-preccv.md b/.changelog/unreleased/features/2400-preccv.md new file mode 100644 index 0000000000..2354aa18d0 --- /dev/null +++ b/.changelog/unreleased/features/2400-preccv.md @@ -0,0 +1,13 @@ +- Enable existing (standalone) chains to use the existing client (and connection) + to the provider chain when becoming a consumer chain. This feature introduces + the following changes. + ([\#2400](https://github.com/cosmos/interchain-security/pull/2400)) + + - Add `connection_id` to `ConsumerInitializationParameters`, the ID of + the connection end _on the provider chain_ on top of which the CCV channel will + be established. Consumer chain owners can set `connection_id` to a valid ID in + order to reuse the underlying clients. + - Add `connection_id` to the consumer genesis state, the ID of the connection + end _on the consumer chain_ on top of which the CCV channel will be established. + If `connection_id` is a valid ID, then the consumer chain will use the underlying + client as the provider client and it will initiate the channel handshake. \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/2400-preccv.md b/.changelog/unreleased/state-breaking/2400-preccv.md new file mode 100644 index 0000000000..6225d97caf --- /dev/null +++ b/.changelog/unreleased/state-breaking/2400-preccv.md @@ -0,0 +1,3 @@ +- Enable existing (standalone) chains to use the existing client (and connection) + to the provider chain when becoming a consumer chain. + ([\#2400](https://github.com/cosmos/interchain-security/pull/2400)) \ No newline at end of file diff --git a/docs/docs/build/modules/02-provider.md b/docs/docs/build/modules/02-provider.md index 8247fb893c..f6729b2272 100644 --- a/docs/docs/build/modules/02-provider.md +++ b/docs/docs/build/modules/02-provider.md @@ -1553,6 +1553,7 @@ init_params: spawn_time: "2024-09-26T06:55:14.616054Z" transfer_timeout_period: 3600s unbonding_period: 1209600s + connection_id: "" metadata: description: description of your chain and all other relevant information metadata: some metadata about your chain @@ -1708,7 +1709,8 @@ where `update-consumer-msg.json` contains: "consumer_redistribution_fraction": "0.75", "blocks_per_distribution_transmission": "1500", "historical_entries": "1000", - "distribution_transmission_channel": "" + "distribution_transmission_channel": "", + "connection_id": "" }, "power_shaping_parameters":{ "top_N": 0, diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index 1894ad7b36..abafb62a43 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -245,7 +245,8 @@ where create_consumer.json has the following structure: "consumer_redistribution_fraction": "0.75", "blocks_per_distribution_transmission": 1000, "historical_entries": 10000, - "distribution_transmission_channel": "" + "distribution_transmission_channel": "", + "connection_id": "" }, "power_shaping_parameters": { "top_N": 0, @@ -344,7 +345,8 @@ where update_consumer.json has the following structure: "consumer_redistribution_fraction": "0.75", "blocks_per_distribution_transmission": 1000, "historical_entries": 10000, - "distribution_transmission_channel": "" + "distribution_transmission_channel": "", + "connection_id": "" }, "power_shaping_parameters": { "top_N": 0, From bc51f316753d6af270139b1b7772423bf0584ba0 Mon Sep 17 00:00:00 2001 From: mpoke Date: Wed, 13 Nov 2024 13:57:04 +0100 Subject: [PATCH 10/25] add TODO --- app/consumer-democracy/app.go | 1 + 1 file changed, 1 insertion(+) diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 865ea7711c..e8903ce78e 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -677,6 +677,7 @@ func New( } } + // TODO: remove this code // For a new consumer chain, this code (together with the entire SetUpgradeHandler) is not needed at all, // upgrade handler code is application specific. However, as an example, standalone to consumer // changeover chains should utilize customized upgrade handler code similar to below. From 1fa7866de9fcb4abf024270ffaa8a69a73ce4c63 Mon Sep 17 00:00:00 2001 From: mpoke Date: Wed, 13 Nov 2024 15:09:30 +0100 Subject: [PATCH 11/25] fix indent --- x/ccv/provider/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index abafb62a43..a4d6539f20 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -246,7 +246,7 @@ where create_consumer.json has the following structure: "blocks_per_distribution_transmission": 1000, "historical_entries": 10000, "distribution_transmission_channel": "", - "connection_id": "" + "connection_id": "" }, "power_shaping_parameters": { "top_N": 0, From 72e406455f9834a92405e640bf6b9ab0094e0fc4 Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Thu, 12 Dec 2024 11:23:25 +0100 Subject: [PATCH 12/25] changeover test --- Makefile | 14 +- tests/interchain/chainsuite/chain.go | 121 +++++++++++- .../chainsuite/chain_spec_provider.go | 23 +-- .../chainsuite/chain_spec_sovereign.go | 52 +++++ tests/interchain/chainsuite/config.go | 74 ++++--- tests/interchain/chainsuite/query_types.go | 21 ++ tests/interchain/chainsuite/relayer.go | 186 ++++++++++++++++++ tests/interchain/changeover_suite.go | 67 +++++++ tests/interchain/changeover_test.go | 119 +++++++++++ tests/interchain/go.mod | 7 +- tests/interchain/go.sum | 7 +- tests/interchain/provider_single_val_test.go | 46 ++--- tests/interchain/provider_suite.go | 21 +- tests/interchain/provider_utils.go | 6 +- 14 files changed, 677 insertions(+), 87 deletions(-) create mode 100644 tests/interchain/chainsuite/chain_spec_sovereign.go create mode 100644 tests/interchain/chainsuite/relayer.go create mode 100644 tests/interchain/changeover_suite.go create mode 100644 tests/interchain/changeover_test.go diff --git a/Makefile b/Makefile index ab56feb717..bea52e7257 100644 --- a/Makefile +++ b/Makefile @@ -53,11 +53,17 @@ test-integration-cov: go test ./tests/integration/... -timeout 30m -coverpkg=./... -coverprofile=integration-profile.out -covermode=atomic # run interchain tests -# we can use PROVIDER_IMAGE_TAG and PROVIDER_IMAGE_NAME to run tests with a desired docker image, -# including a locally built one that, for example, contains some of our changes that are not yet on the main branch. -# if not provided, default value for PROVIDER_IMAGE_TAG is "latest" and for PROVIDER_IMAGE_NAME "ghcr.io/cosmos/interchain-security" +# we can use PROVIDER_IMAGE_TAG, PROVIDER_IMAGE_NAME, SOUVEREIGN_IMAGE_TAG, and SOUVEREIGN_IMAGE_NAME to run tests with desired docker images, +# including locally built ones that, for example, contain some of our changes that are not yet on the main branch. +# if not provided, default value for PROVIDER_IMAGE_TAG and SOUVEREIGN_IMAGE_TAG is "latest" and for PROVIDER_IMAGE_NAME +# and SOUVEREIGN_IMAGE_NAME is "ghcr.io/cosmos/interchain-security" test-interchain: - cd tests/interchain && PROVIDER_IMAGE_NAME=$(PROVIDER_IMAGE_NAME) PROVIDER_IMAGE_TAG=$(PROVIDER_IMAGE_TAG) go test ./... -timeout 30m + cd tests/interchain && \ + PROVIDER_IMAGE_NAME=$(PROVIDER_IMAGE_NAME) \ + PROVIDER_IMAGE_TAG=$(PROVIDER_IMAGE_TAG) \ + SOUVEREIGN_IMAGE_NAME=$(SOUVEREIGN_IMAGE_NAME) \ + SOUVEREIGN_IMAGE_TAG=$(SOUVEREIGN_IMAGE_TAG) \ + go test ./... -timeout 30m # run mbt tests test-mbt: diff --git a/tests/interchain/chainsuite/chain.go b/tests/interchain/chainsuite/chain.go index d6f5456563..082abac3ed 100644 --- a/tests/interchain/chainsuite/chain.go +++ b/tests/interchain/chainsuite/chain.go @@ -4,10 +4,13 @@ import ( "context" "encoding/json" "fmt" + "io" + "net/http" "path" "strconv" "strings" "sync" + "time" sdkmath "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" @@ -16,6 +19,7 @@ import ( "github.com/strangelove-ventures/interchaintest/v8" "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" + "github.com/tidwall/gjson" "golang.org/x/sync/errgroup" ) @@ -48,8 +52,8 @@ func chainFromCosmosChain(cosmos *cosmos.CosmosChain, relayerWallet ibc.Wallet, return c, nil } -// CreateProviderChain creates a single new chain with the given version and returns the chain object. -func CreateProviderChain(ctx context.Context, testName interchaintest.TestName, spec *interchaintest.ChainSpec) (*Chain, error) { +// CreateChain creates a single new chain with the given version and returns the chain object. +func CreateChain(ctx context.Context, testName interchaintest.TestName, spec *interchaintest.ChainSpec) (*Chain, error) { cf := interchaintest.NewBuiltinChainFactory( GetLogger(ctx), []*interchaintest.ChainSpec{spec}, @@ -155,6 +159,97 @@ func getValidatorWallets(ctx context.Context, chain *Chain) ([]ValidatorWallet, return wallets, nil } +// UpdateAndVerifyStakeChange updates the staking amount on the provider chain and verifies that the change is reflected on the consumer side +func (p *Chain) UpdateAndVerifyStakeChange(ctx context.Context, consumer *Chain, relayer *Relayer, amount, valIdx int) error { + + providerAddress := p.ValidatorWallets[valIdx] + + providerHex, err := p.GetValidatorHexAddress(ctx, valIdx) + if err != nil { + return err + } + consumerHex, err := consumer.GetValidatorHexAddress(ctx, valIdx) + if err != nil { + return err + } + + providerPowerBefore, err := p.GetValidatorPower(ctx, providerHex) + if err != nil { + return err + } + + // increase the stake for the given validator + _, err = p.Validators[valIdx].ExecTx(ctx, providerAddress.Moniker, + "staking", "delegate", + providerAddress.ValoperAddress, fmt.Sprintf("%d%s", amount, p.Config().Denom), + ) + if err != nil { + return err + } + + // check that the validator power is updated on both, provider and consumer chains + tCtx, tCancel := context.WithTimeout(ctx, 5*time.Minute) + defer tCancel() + var retErr error + for tCtx.Err() == nil { + retErr = nil + providerPower, err := p.GetValidatorPower(ctx, providerHex) + if err != nil { + return err + } + consumerPower, err := consumer.GetValidatorPower(ctx, consumerHex) + if err != nil { + return err + } + if providerPowerBefore >= providerPower { + retErr = fmt.Errorf("provider power did not increase after delegation") + } else if providerPower != consumerPower { + retErr = fmt.Errorf("consumer power did not update after provider delegation") + } + if retErr == nil { + break + } + time.Sleep(CommitTimeout) + } + return retErr +} + +func (p *Chain) GetValidatorHexAddress(ctx context.Context, valIdx int) (string, error) { + json, err := p.Validators[valIdx].ReadFile(ctx, "config/priv_validator_key.json") + if err != nil { + return "", err + } + return gjson.GetBytes(json, "address").String(), nil +} + +func (c *Chain) GetValidatorPower(ctx context.Context, hexaddr string) (int64, error) { + var power int64 + err := checkEndpoint(c.GetHostRPCAddress()+"/validators", func(b []byte) error { + power = gjson.GetBytes(b, fmt.Sprintf("result.validators.#(address==\"%s\").voting_power", hexaddr)).Int() + if power == 0 { + return fmt.Errorf("validator %s power not found; validators are: %s", hexaddr, string(b)) + } + return nil + }) + if err != nil { + return 0, err + } + return power, nil +} + +func checkEndpoint(url string, f func([]byte) error) error { + resp, err := http.Get(url) //nolint:gosec + if err != nil { + return err + } + defer resp.Body.Close() + bts, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + return f(bts) +} + func (c *Chain) WaitForProposalStatus(ctx context.Context, proposalID string, status govv1.ProposalStatus) error { propID, err := strconv.ParseInt(proposalID, 10, 64) if err != nil { @@ -201,8 +296,8 @@ func (c *Chain) SubmitAndVoteForProposal(ctx context.Context, prop cosmos.TxProp } // builds proposal message, submits, votes and wait for proposal expected status -func (c *Chain) ExecuteProposalMsg(ctx context.Context, proposalMsg cosmos.ProtoMessage, proposer string, chainName string, vote string, expectedStatus govv1.ProposalStatus, expedited bool) error { - proposal, err := c.BuildProposal([]cosmos.ProtoMessage{proposalMsg}, chainName, "summary", "", GovMinDepositString, proposer, false) +func (c *Chain) ExecuteProposalMsg(ctx context.Context, proposalMsg cosmos.ProtoMessage, proposer string, title string, vote string, expectedStatus govv1.ProposalStatus, expedited bool) error { + proposal, err := c.BuildProposal([]cosmos.ProtoMessage{proposalMsg}, title, "summary", "", GovMinDepositString, proposer, false) if err != nil { return err } @@ -439,6 +534,24 @@ func (c *Chain) GetValidatorKey(ctx context.Context, validatorIndex int) (string return address, nil } +func (c *Chain) GetCcvConsumerParams(ctx context.Context) (ConsumerParamsResponse, error) { + queryRes, _, err := c.GetNode().ExecQuery( + ctx, + "ccvconsumer", "params", + ) + if err != nil { + return ConsumerParamsResponse{}, err + } + + var queryResponse ConsumerParamsResponse + err = json.Unmarshal([]byte(queryRes), &queryResponse) + if err != nil { + return ConsumerParamsResponse{}, err + } + + return queryResponse, nil +} + func getEvtAttribute(events []abci.Event, evtType string, key string) (string, bool) { for _, evt := range events { if evt.GetType() == evtType { diff --git a/tests/interchain/chainsuite/chain_spec_provider.go b/tests/interchain/chainsuite/chain_spec_provider.go index 9643f1dcd2..b6018e028c 100644 --- a/tests/interchain/chainsuite/chain_spec_provider.go +++ b/tests/interchain/chainsuite/chain_spec_provider.go @@ -1,15 +1,13 @@ package chainsuite import ( - "strconv" - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8" ) -func GetProviderSpec(validatorCount int) *interchaintest.ChainSpec { +func GetProviderSpec(validatorCount int, modifiedGenesis []cosmos.GenesisKV) *interchaintest.ChainSpec { fullNodes := FullNodeCount validators := validatorCount @@ -33,25 +31,8 @@ func GetProviderSpec(validatorCount int) *interchaintest.ChainSpec { Repository: ProviderImageName(), UIDGID: "1025:1025", }}, - ModifyGenesis: cosmos.ModifyGenesis(providerModifiedGenesis()), + ModifyGenesis: cosmos.ModifyGenesis(modifiedGenesis), ModifyGenesisAmounts: DefaultGenesisAmounts(Stake), }, } } - -func providerModifiedGenesis() []cosmos.GenesisKV { - return []cosmos.GenesisKV{ - cosmos.NewGenesisKV("app_state.staking.params.unbonding_time", ProviderUnbondingTime.String()), - cosmos.NewGenesisKV("app_state.gov.params.voting_period", GovVotingPeriod.String()), - cosmos.NewGenesisKV("app_state.gov.params.max_deposit_period", GovDepositPeriod.String()), - cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.denom", Stake), - cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.amount", strconv.Itoa(GovMinDepositAmount)), - cosmos.NewGenesisKV("app_state.slashing.params.signed_blocks_window", strconv.Itoa(ProviderSlashingWindow)), - cosmos.NewGenesisKV("app_state.slashing.params.downtime_jail_duration", DowntimeJailDuration.String()), - cosmos.NewGenesisKV("app_state.slashing.params.slash_fraction_double_sign", SlashFractionDoubleSign), - cosmos.NewGenesisKV("app_state.provider.params.slash_meter_replenish_period", ProviderReplenishPeriod), - cosmos.NewGenesisKV("app_state.provider.params.slash_meter_replenish_fraction", ProviderReplenishFraction), - cosmos.NewGenesisKV("app_state.provider.params.blocks_per_epoch", "1"), - cosmos.NewGenesisKV("app_state.staking.params.max_validators", "1"), - } -} diff --git a/tests/interchain/chainsuite/chain_spec_sovereign.go b/tests/interchain/chainsuite/chain_spec_sovereign.go new file mode 100644 index 0000000000..be396f6678 --- /dev/null +++ b/tests/interchain/chainsuite/chain_spec_sovereign.go @@ -0,0 +1,52 @@ +package chainsuite + +import ( + "strconv" + + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/ibc" +) + +func GetSovereignSpec() *interchaintest.ChainSpec { + fullNodes := FullNodeCount + validators := 1 + + return &interchaintest.ChainSpec{ + ChainName: SovereignToConsumerChainID, + NumFullNodes: &fullNodes, + NumValidators: &validators, + ChainConfig: ibc.ChainConfig{ + ChainID: SovereignToConsumerChainID, + Bin: SovereignBin, + Denom: Stake, + Type: CosmosChainType, + GasPrices: GasPrices + Stake, + GasAdjustment: 2.0, + TrustingPeriod: "336h", + CoinType: "118", + Images: []ibc.DockerImage{ + { + Repository: SouvereignImageName(), + Version: SouvereignImageVersion(), + UIDGID: "1025:1025", + }, + }, + ConfigFileOverrides: map[string]any{ + "config/config.toml": DefaultConfigToml(), + }, + Bech32Prefix: Bech32PrefixConsumer, + ModifyGenesis: cosmos.ModifyGenesis(sovereignModifiedGenesis()), + ModifyGenesisAmounts: DefaultGenesisAmounts(Stake), + }, + } +} + +func sovereignModifiedGenesis() []cosmos.GenesisKV { + return []cosmos.GenesisKV{ + cosmos.NewGenesisKV("app_state.gov.params.voting_period", GovVotingPeriod.String()), + cosmos.NewGenesisKV("app_state.gov.params.max_deposit_period", GovDepositPeriod.String()), + cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.denom", Stake), + cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.amount", strconv.Itoa(GovMinDepositAmount)), + } +} diff --git a/tests/interchain/chainsuite/config.go b/tests/interchain/chainsuite/config.go index 36b865a55a..7988937996 100644 --- a/tests/interchain/chainsuite/config.go +++ b/tests/interchain/chainsuite/config.go @@ -11,32 +11,36 @@ import ( ) const ( - ProviderBin = "interchain-security-pd" - ProviderBech32Prefix = "cosmos" - ProviderValOperPrefix = "cosmosvaloper" - ProviderChainID = "ics-provider" - Stake = "stake" - DowntimeJailDuration = 10 * time.Second - SlashFractionDoubleSign = "0.05" - ProviderSlashingWindow = 10 - ProviderUnbondingTime = 10 * time.Second - ProviderReplenishPeriod = "2s" - ProviderReplenishFraction = "1.00" - GovMinDepositAmount = 1000 - GovMinDepositString = "1000" + Stake - GovDepositPeriod = 10 * time.Second - GovVotingPeriod = 15 * time.Second - GasPrices = "0.005" - UpgradeDelta = 30 - SlashingWindowConsumer = 20 - CommitTimeout = 2 * time.Second - TotalValidatorFunds = 11_000_000_000 - ValidatorFunds = 30_000_000 - FullNodeCount = 0 - ChainSpawnWait = 155 * time.Second - CosmosChainType = "cosmos" - GovModuleAddress = "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" - TestWalletsNumber = 20 // Ensure that test accounts are used in a way that maintains the mutual independence of tests + ProviderBin = "interchain-security-pd" + ProviderBech32Prefix = "cosmos" + ProviderValOperPrefix = "cosmosvaloper" + ProviderChainID = "ics-provider" + SovereignToConsumerChainID = "ics-sovereign-consumer" + SovereignBin = "interchain-security-sd" + Bech32PrefixConsumer = "consumer" + Stake = "stake" + DowntimeJailDuration = 10 * time.Second + SlashFractionDoubleSign = "0.05" + ProviderSlashingWindow = 10 + ProviderUnbondingTime = 10 * time.Second + ProviderReplenishPeriod = "2s" + ProviderReplenishFraction = "1.00" + GovMinDepositAmount = 1000 + GovMinDepositString = "1000" + Stake + GovDepositPeriod = 10 * time.Second + GovVotingPeriod = 15 * time.Second + GasPrices = "0.005" + UpgradeDelta = 30 + SlashingWindowConsumer = 20 + CommitTimeout = 2 * time.Second + TotalValidatorFunds = 11_000_000_000 + ValidatorFunds = 30_000_000 + FullNodeCount = 0 + ChainSpawnWait = 155 * time.Second + CosmosChainType = "cosmos" + ProviderGovModuleAddress = "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" + ConsumerGovModuleAddress = "consumer10d07y265gmmuvt4z0w9aw880jnsr700jlh7295" + TestWalletsNumber = 20 ) func DefaultConfigToml() testutil.Toml { @@ -79,3 +83,21 @@ func ProviderImageName() string { return providerImageName } + +func SouvereignImageVersion() string { + souvereignImageVersion := os.Getenv("SOUVEREIGN_IMAGE_TAG") + if souvereignImageVersion == "" { + souvereignImageVersion = "latest" + } + + return souvereignImageVersion +} + +func SouvereignImageName() string { + souvereignImageName := os.Getenv("SOUVEREIGN_IMAGE_NAME") + if souvereignImageName == "" { + souvereignImageName = "ghcr.io/cosmos/interchain-security" + } + + return souvereignImageName +} diff --git a/tests/interchain/chainsuite/query_types.go b/tests/interchain/chainsuite/query_types.go index 05efddf405..fd19028cc8 100644 --- a/tests/interchain/chainsuite/query_types.go +++ b/tests/interchain/chainsuite/query_types.go @@ -188,3 +188,24 @@ type ValidatorConsumerAddressResponse struct { type ValidatorProviderAddressResponse struct { ProviderAddress string `json:"provider_address"` } + +type ConsumerParamsResponse struct { + Params Params `json:"params"` +} + +type ConsumerParams struct { + Enabled bool `json:"enabled"` + BlocksPerDistributionTransmission string `json:"blocks_per_distribution_transmission"` + DistributionTransmissionChannel string `json:"distribution_transmission_channel"` + ProviderFeePoolAddrStr string `json:"provider_fee_pool_addr_str"` + CCVTimeoutPeriod string `json:"ccv_timeout_period"` + TransferTimeoutPeriod string `json:"transfer_timeout_period"` + ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` + HistoricalEntries string `json:"historical_entries"` + UnbondingPeriod string `json:"unbonding_period"` + SoftOptOutThreshold string `json:"soft_opt_out_threshold"` + RewardDenoms []string `json:"reward_denoms"` + ProviderRewardDenoms []string `json:"provider_reward_denoms"` + RetryDelayPeriod string `json:"retry_delay_period"` + ConsumerID string `json:"consumer_id"` +} diff --git a/tests/interchain/chainsuite/relayer.go b/tests/interchain/chainsuite/relayer.go new file mode 100644 index 0000000000..6880f9e423 --- /dev/null +++ b/tests/interchain/chainsuite/relayer.go @@ -0,0 +1,186 @@ +package chainsuite + +import ( + "context" + "encoding/json" + "fmt" + "sort" + "time" + + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "github.com/strangelove-ventures/interchaintest/v8/relayer" + "github.com/tidwall/gjson" +) + +type Relayer struct { + ibc.Relayer +} + +func NewRelayer(ctx context.Context, testName interchaintest.TestName) (*Relayer, error) { + dockerClient, dockerNetwork := GetDockerContext(ctx) + rly := interchaintest.NewBuiltinRelayerFactory( + ibc.Hermes, + GetLogger(ctx), + relayer.CustomDockerImage("ghcr.io/informalsystems/hermes", "1.10.3", "2000:2000"), + ).Build(testName, dockerClient, dockerNetwork) + return &Relayer{Relayer: rly}, nil +} + +func (r *Relayer) SetupChainKeys(ctx context.Context, chain *Chain) error { + rep := GetRelayerExecReporter(ctx) + rpcAddr, grpcAddr := chain.GetRPCAddress(), chain.GetGRPCAddress() + if !r.UseDockerNetwork() { + rpcAddr, grpcAddr = chain.GetHostRPCAddress(), chain.GetHostGRPCAddress() + } + + chainName := chain.Config().ChainID + if err := r.AddChainConfiguration(ctx, rep, chain.Config(), chainName, rpcAddr, grpcAddr); err != nil { + return err + } + + return r.RestoreKey(ctx, rep, chain.Config(), chainName, chain.RelayerWallet.Mnemonic()) +} + +func (r *Relayer) GetTransferChannel(ctx context.Context, chain, counterparty *Chain) (*ibc.ChannelOutput, error) { + return r.GetChannelWithPort(ctx, chain, counterparty, "transfer") +} + +func (r *Relayer) GetChannelWithPort(ctx context.Context, chain, counterparty *Chain, portID string) (*ibc.ChannelOutput, error) { + clients, err := r.GetClients(ctx, GetRelayerExecReporter(ctx), chain.Config().ChainID) + if err != nil { + return nil, err + } + var client *ibc.ClientOutput + for _, c := range clients { + if c.ClientState.ChainID == counterparty.Config().ChainID { + client = c + break + } + } + if client == nil { + return nil, fmt.Errorf("no client found for chain %s", counterparty.Config().ChainID) + } + + stdout, _, err := chain.GetNode().ExecQuery(ctx, "ibc", "connection", "connections") + if err != nil { + return nil, fmt.Errorf("error querying connections: %w", err) + } + connections := gjson.GetBytes(stdout, fmt.Sprintf("connections.#(client_id==\"%s\")#.id", client.ClientID)).Array() + if len(connections) == 0 { + return nil, fmt.Errorf("no connections found for client %s", client.ClientID) + } + for _, connID := range connections { + stdout, _, err := chain.GetNode().ExecQuery(ctx, "ibc", "channel", "connections", connID.String()) + if err != nil { + return nil, err + } + channelJSON := gjson.GetBytes(stdout, fmt.Sprintf("channels.#(port_id==\"%s\")", portID)).String() + if channelJSON != "" { + channelOutput := &ibc.ChannelOutput{} + if err := json.Unmarshal([]byte(channelJSON), channelOutput); err != nil { + return nil, fmt.Errorf("error unmarshalling channel output %s: %w", channelJSON, err) + } + return channelOutput, nil + } + } + return nil, fmt.Errorf("no channel found for port %s", portID) +} + +func (r *Relayer) RestartRelayer(ctx context.Context) error { + rep := GetRelayerExecReporter(ctx) + if err := r.StopRelayer(ctx, rep); err != nil { + return err + } + if err := r.StartRelayer(ctx, rep); err != nil { + return err + } + + return nil +} + +func (r *Relayer) ConnectProviderConsumer(ctx context.Context, provider *Chain, consumer *Chain) error { + icsPath := relayerICSPathFor(provider, consumer) + rep := GetRelayerExecReporter(ctx) + if err := r.GeneratePath(ctx, rep, consumer.Config().ChainID, provider.Config().ChainID, icsPath); err != nil { + return err + } + + consumerClients, err := r.GetClients(ctx, rep, consumer.Config().ChainID) + if err != nil { + return err + } + sort.Slice(consumerClients, func(i, j int) bool { + return consumerClients[i].ClientID > consumerClients[j].ClientID + }) + var consumerClient *ibc.ClientOutput + for _, client := range consumerClients { + if client.ClientState.ChainID == provider.Config().ChainID { + consumerClient = client + break + } + } + if consumerClient == nil { + return fmt.Errorf("consumer chain %s does not have a client tracking the provider chain %s", consumer.Config().ChainID, provider.Config().ChainID) + } + consumerClientID := consumerClient.ClientID + + providerClients, err := r.GetClients(ctx, rep, provider.Config().ChainID) + if err != nil { + return err + } + sort.Slice(providerClients, func(i, j int) bool { + return providerClients[i].ClientID > providerClients[j].ClientID + }) + + var providerClient *ibc.ClientOutput + for _, client := range providerClients { + if client.ClientState.ChainID == consumer.Config().ChainID { + providerClient = client + break + } + } + if providerClient == nil { + return fmt.Errorf("provider chain %s does not have a client tracking the consumer chain %s for path %s on relayer %s", + provider.Config().ChainID, consumer.Config().ChainID, icsPath, r) + } + providerClientID := providerClient.ClientID + + if err := r.UpdatePath(ctx, rep, icsPath, ibc.PathUpdateOptions{ + SrcClientID: &consumerClientID, + DstClientID: &providerClientID, + }); err != nil { + return err + } + + if err := r.CreateConnections(ctx, rep, icsPath); err != nil { + return err + } + + if err := r.CreateChannel(ctx, rep, icsPath, ibc.CreateChannelOptions{ + SourcePortName: "consumer", + DestPortName: "provider", + Order: ibc.Ordered, + Version: "1", + }); err != nil { + return err + } + + tCtx, tCancel := context.WithTimeout(ctx, 30*CommitTimeout) + defer tCancel() + for tCtx.Err() == nil { + var ch *ibc.ChannelOutput + ch, err = r.GetTransferChannel(ctx, provider, consumer) + if err == nil && ch != nil { + break + } else if err == nil { + err = fmt.Errorf("channel not found") + } + time.Sleep(CommitTimeout) + } + return err +} + +func relayerICSPathFor(chainA, chainB *Chain) string { + return fmt.Sprintf("ics-%s-%s", chainA.Config().ChainID, chainB.Config().ChainID) +} diff --git a/tests/interchain/changeover_suite.go b/tests/interchain/changeover_suite.go new file mode 100644 index 0000000000..3419905eab --- /dev/null +++ b/tests/interchain/changeover_suite.go @@ -0,0 +1,67 @@ +package interchain + +import ( + "context" + "cosmos/interchain-security/tests/interchain/chainsuite" + "strconv" + + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/stretchr/testify/suite" +) + +type ChangeoverSuite struct { + suite.Suite + Provider *chainsuite.Chain + Consumer *chainsuite.Chain + Relayer *chainsuite.Relayer + ctx context.Context +} + +func (s *ChangeoverSuite) SetupSuite() { + ctx, err := chainsuite.NewSuiteContext(&s.Suite) + s.Require().NoError(err) + s.ctx = ctx + + // create and start provider chain + s.Provider, err = chainsuite.CreateChain(s.GetContext(), s.T(), chainsuite.GetProviderSpec(1, provChangeoverModifiedGenesis())) + s.Require().NoError(err) + + // create and start sovereign chain that will later changeover to consumer + s.Consumer, err = chainsuite.CreateChain(s.GetContext(), s.T(), chainsuite.GetSovereignSpec()) + s.Require().NoError(err) + + // setup hermes relayer + relayer, err := chainsuite.NewRelayer(s.GetContext(), s.T()) + s.Require().NoError(err) + s.Relayer = relayer + + err = relayer.SetupChainKeys(s.GetContext(), s.Provider) + s.Require().NoError(err) + s.Require().NoError(relayer.RestartRelayer(ctx)) + + err = relayer.SetupChainKeys(s.GetContext(), s.Consumer) + s.Require().NoError(err) + s.Require().NoError(relayer.RestartRelayer(ctx)) +} + +func (s *ChangeoverSuite) GetContext() context.Context { + s.Require().NotNil(s.ctx, "Tried to GetContext before it was set. SetupSuite must run first") + return s.ctx +} + +func provChangeoverModifiedGenesis() []cosmos.GenesisKV { + return []cosmos.GenesisKV{ + cosmos.NewGenesisKV("app_state.staking.params.unbonding_time", (chainsuite.ProviderUnbondingTime * 10000000).String()), + cosmos.NewGenesisKV("app_state.gov.params.voting_period", chainsuite.GovVotingPeriod.String()), + cosmos.NewGenesisKV("app_state.gov.params.max_deposit_period", chainsuite.GovDepositPeriod.String()), + cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.denom", chainsuite.Stake), + cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.amount", strconv.Itoa(chainsuite.GovMinDepositAmount)), + cosmos.NewGenesisKV("app_state.slashing.params.signed_blocks_window", strconv.Itoa(chainsuite.ProviderSlashingWindow)), + cosmos.NewGenesisKV("app_state.slashing.params.downtime_jail_duration", chainsuite.DowntimeJailDuration.String()), + cosmos.NewGenesisKV("app_state.slashing.params.slash_fraction_double_sign", chainsuite.SlashFractionDoubleSign), + cosmos.NewGenesisKV("app_state.provider.params.slash_meter_replenish_period", chainsuite.ProviderReplenishPeriod), + cosmos.NewGenesisKV("app_state.provider.params.slash_meter_replenish_fraction", chainsuite.ProviderReplenishFraction), + cosmos.NewGenesisKV("app_state.provider.params.blocks_per_epoch", "1"), + cosmos.NewGenesisKV("app_state.staking.params.max_validators", "1"), + } +} diff --git a/tests/interchain/changeover_test.go b/tests/interchain/changeover_test.go new file mode 100644 index 0000000000..f1f4941ed2 --- /dev/null +++ b/tests/interchain/changeover_test.go @@ -0,0 +1,119 @@ +package interchain + +import ( + "context" + "cosmos/interchain-security/tests/interchain/chainsuite" + "fmt" + "testing" + "time" + + upgradetypes "cosmossdk.io/x/upgrade/types" + + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + + providertypes "github.com/cosmos/interchain-security/v6/x/ccv/provider/types" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/testutil" + "github.com/stretchr/testify/suite" + "github.com/tidwall/sjson" + "golang.org/x/sync/errgroup" +) + +func TestChangeoverSuite(t *testing.T) { + s := &ChangeoverSuite{} + + suite.Run(t, s) +} + +func (s *ChangeoverSuite) TestSovereignToConsumer() { + // submit MsgCreateConsumer and verify that the chain is in launched phase + currentHeight, err := s.Consumer.Height(s.GetContext()) + s.Require().NoError(err) + spawnTime := time.Now().Add(time.Hour) + initializationParams := consumerInitParamsTemplate(&spawnTime) + initialHeight := uint64(currentHeight) + 60 + initializationParams.InitialHeight = clienttypes.Height{ + RevisionNumber: clienttypes.ParseChainID(s.Consumer.Config().ChainID), + RevisionHeight: initialHeight, + } + powerShapingParams := powerShapingParamsTemplate() + createConsumerMsg := msgCreateConsumer(s.Consumer.Config().ChainID, initializationParams, powerShapingParams, nil, s.Provider.ValidatorWallets[0].Address) + consumerID, err := s.Provider.CreateConsumer(s.GetContext(), createConsumerMsg, chainsuite.ValidatorMoniker) + s.Require().NoError(err) + // opt in validator + s.Require().NoError(s.Provider.OptIn(s.GetContext(), consumerID, 0)) + // assign consumer key + valConsumerKey, err := s.Consumer.GetValidatorKey(s.GetContext(), 0) + s.Require().NoError(err) + s.Require().NoError(s.Provider.AssignKey(s.GetContext(), consumerID, 0, valConsumerKey)) + // update spawn time + initializationParams.SpawnTime = time.Now() + updateMsg := &providertypes.MsgUpdateConsumer{ + Owner: s.Provider.ValidatorWallets[0].Address, + ConsumerId: consumerID, + NewOwnerAddress: s.Provider.ValidatorWallets[0].Address, + InitializationParameters: initializationParams, + PowerShapingParameters: powerShapingParams, + } + s.Require().NoError(s.Provider.UpdateConsumer(s.GetContext(), updateMsg, s.Provider.ValidatorWallets[0].Address)) + s.Require().NoError(testutil.WaitForBlocks(s.GetContext(), 2, s.Provider)) + consumerChain, err := s.Provider.GetConsumerChain(s.GetContext(), consumerID) + s.Require().NoError(err) + s.Require().Equal(providertypes.CONSUMER_PHASE_LAUNCHED.String(), consumerChain.Phase) + + // submit sw upgrade proposal + upgradeMsg := &upgradetypes.MsgSoftwareUpgrade{ + Authority: chainsuite.ConsumerGovModuleAddress, + Plan: upgradetypes.Plan{ + Name: "sovereign-changeover", + Height: int64(initialHeight) - 3, + }, + } + s.Require().NoError(s.Consumer.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ConsumerGovModuleAddress, "Changeover", cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + + // wait for sw upgrade height + currentHeight, err = s.Consumer.Height(s.GetContext()) + s.Require().NoError(err) + timeoutCtx, timeoutCtxCancel := context.WithTimeout(s.GetContext(), (time.Duration(int64(initialHeight)-currentHeight)+10)*chainsuite.CommitTimeout) + defer timeoutCtxCancel() + err = testutil.WaitForBlocks(timeoutCtx, int(int64(initialHeight)-currentHeight)+3, s.Consumer) + s.Require().Error(err) + + // stop sovereign chain + s.Require().NoError(s.Consumer.StopAllNodes(s.GetContext())) + + genesis, err := s.Consumer.GetNode().GenesisFileContent(s.GetContext()) + s.Require().NoError(err) + + // insert consumer genesis section + ccvState, _, err := s.Provider.GetNode().ExecQuery(s.GetContext(), "provider", "consumer-genesis", consumerID) + s.Require().NoError(err) + genesis, err = sjson.SetRawBytes(genesis, "app_state.ccvconsumer", ccvState) + s.Require().NoError(err) + + eg := errgroup.Group{} + for _, val := range s.Consumer.Validators { + val := val + eg.Go(func() error { + if err := val.OverwriteGenesisFile(s.GetContext(), []byte(genesis)); err != nil { + return err + } + return val.WriteFile(s.GetContext(), []byte(genesis), ".sovereign/config/genesis.json") + }) + } + s.Require().NoError(eg.Wait()) + + // replace the binary and restart consumer node + s.Consumer.ChangeBinary(s.GetContext(), "interchain-security-cdd") + s.Require().NoError(s.Consumer.StartAllNodes(s.GetContext())) + s.Require().NoError(s.Relayer.ConnectProviderConsumer(s.GetContext(), s.Provider, s.Consumer)) + s.Require().NoError(s.Relayer.StopRelayer(s.GetContext(), chainsuite.GetRelayerExecReporter(s.GetContext()))) + s.Require().NoError(s.Relayer.StartRelayer(s.GetContext(), chainsuite.GetRelayerExecReporter(s.GetContext()))) + params, err := s.Consumer.GetCcvConsumerParams(s.ctx) + s.Require().NoError(err) + s.Require().True(params.Params.HistoricalEntries == fmt.Sprint(initializationParams.HistoricalEntries)) + // check if consumer is connected and functional + s.Require().NoError(s.Provider.UpdateAndVerifyStakeChange(s.GetContext(), s.Consumer, s.Relayer, 1_000_000, 0)) +} diff --git a/tests/interchain/go.mod b/tests/interchain/go.mod index 8215ada4a2..3d8c8271a0 100644 --- a/tests/interchain/go.mod +++ b/tests/interchain/go.mod @@ -6,6 +6,7 @@ toolchain go1.22.10 require ( cosmossdk.io/math v1.4.0 + cosmossdk.io/x/upgrade v0.1.4 github.com/cometbft/cometbft v0.38.15 github.com/cosmos/cosmos-sdk v0.50.10 github.com/cosmos/ibc-go/v8 v8.5.2 @@ -13,6 +14,8 @@ require ( github.com/docker/docker v25.0.6+incompatible github.com/strangelove-ventures/interchaintest/v8 v8.7.1 github.com/stretchr/testify v1.9.0 + github.com/tidwall/gjson v1.18.0 + github.com/tidwall/sjson v1.2.5 go.uber.org/zap v1.27.0 golang.org/x/sync v0.9.0 ) @@ -34,7 +37,6 @@ require ( cosmossdk.io/x/evidence v0.1.1 // indirect cosmossdk.io/x/feegrant v0.1.1 // indirect cosmossdk.io/x/tx v0.13.5 // indirect - cosmossdk.io/x/upgrade v0.1.4 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect @@ -226,7 +228,6 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect - github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect @@ -290,7 +291,7 @@ replace ( github.com/cosmos/interchain-security/v6 => github.com/cosmos/interchain-security/v6 v6.0.0-20241203112553-01f9698b4450 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 // Remove this when strangelove-ventures updates the interchain tests to import ICS v6 - github.com/strangelove-ventures/interchaintest/v8 => github.com/stana-miric/interchaintest/v8 v8.0.0-20241022073631-60f2480aacd4 + github.com/strangelove-ventures/interchaintest/v8 => github.com/stana-miric/interchaintest/v8 v8.0.0-20241213083053-58af9adbcc58 github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) diff --git a/tests/interchain/go.sum b/tests/interchain/go.sum index 0fc000ff06..5d989200bd 100644 --- a/tests/interchain/go.sum +++ b/tests/interchain/go.sum @@ -1133,8 +1133,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= -github.com/stana-miric/interchaintest/v8 v8.0.0-20241022073631-60f2480aacd4 h1:D7TeNWCVargpSbh/+sG0lNIxTa0XTRoZkNgwTY5riPw= -github.com/stana-miric/interchaintest/v8 v8.0.0-20241022073631-60f2480aacd4/go.mod h1:OOAl+5e4or9FdILfKprkqeVt/WjZt0qBv7bp5fKbBSc= +github.com/stana-miric/interchaintest/v8 v8.0.0-20241213083053-58af9adbcc58 h1:8VyNziFamlVhuhcLpp+6BoR4OwHS1BsRADno3IHfrKo= +github.com/stana-miric/interchaintest/v8 v8.0.0-20241213083053-58af9adbcc58/go.mod h1:OOAl+5e4or9FdILfKprkqeVt/WjZt0qBv7bp5fKbBSc= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1170,12 +1170,15 @@ github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2l github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= diff --git a/tests/interchain/provider_single_val_test.go b/tests/interchain/provider_single_val_test.go index 9efe053ffa..f201d81e36 100644 --- a/tests/interchain/provider_single_val_test.go +++ b/tests/interchain/provider_single_val_test.go @@ -316,24 +316,24 @@ func (s *SingleValidatorProviderSuite) TestProviderTransformOptInToTopN() { upgradeMsg := &providertypes.MsgUpdateConsumer{ Owner: testAcc, ConsumerId: consumerId, - NewOwnerAddress: chainsuite.GovModuleAddress, + NewOwnerAddress: chainsuite.ProviderGovModuleAddress, } s.Require().NoError(s.Provider.UpdateConsumer(s.GetContext(), upgradeMsg, testAccKey)) consumerChain, err = s.Provider.GetConsumerChain(s.GetContext(), consumerId) s.Require().NoError(err) - s.Require().Equal(chainsuite.GovModuleAddress, consumerChain.OwnerAddress) + s.Require().Equal(chainsuite.ProviderGovModuleAddress, consumerChain.OwnerAddress) // Confirm that the chain can be updated to a lower TopN spawTimeFromNow := 10 * time.Second initParams.SpawnTime = time.Now().Add(spawTimeFromNow) powerShapingParams.Top_N = 50 upgradeMsg = &providertypes.MsgUpdateConsumer{ - Owner: chainsuite.GovModuleAddress, + Owner: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerId, - NewOwnerAddress: chainsuite.GovModuleAddress, + NewOwnerAddress: chainsuite.ProviderGovModuleAddress, InitializationParameters: initParams, PowerShapingParameters: powerShapingParams, } - s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) time.Sleep(spawTimeFromNow) s.Require().NoError(testutil.WaitForBlocks(s.GetContext(), 1, s.Provider)) updatedChain, err := s.Provider.GetConsumerChain(s.GetContext(), consumerId) @@ -344,12 +344,12 @@ func (s *SingleValidatorProviderSuite) TestProviderTransformOptInToTopN() { //Confirm that the chain can be updated to a higher TopN powerShapingParams.Top_N = 100 upgradeMsg = &providertypes.MsgUpdateConsumer{ - Owner: chainsuite.GovModuleAddress, + Owner: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerId, - NewOwnerAddress: chainsuite.GovModuleAddress, + NewOwnerAddress: chainsuite.ProviderGovModuleAddress, PowerShapingParameters: powerShapingParams, } - s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) updatedChain, err = s.Provider.GetConsumerChain(s.GetContext(), consumerId) s.Require().NoError(err) s.Require().Equal(providertypes.CONSUMER_PHASE_LAUNCHED.String(), updatedChain.Phase) @@ -357,11 +357,11 @@ func (s *SingleValidatorProviderSuite) TestProviderTransformOptInToTopN() { // Confirm that the owner of the chain cannot change as long as it remains a Top N chain upgradeMsg = &providertypes.MsgUpdateConsumer{ - Owner: chainsuite.GovModuleAddress, + Owner: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerId, NewOwnerAddress: testAcc, } - s.Require().Error(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + s.Require().Error(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) } // Create a Top N chain, and transform it to an opt-in via `tx gov submit-proposal` using MsgUpdateConsumer @@ -375,20 +375,20 @@ func (s *SingleValidatorProviderSuite) TestProviderTransformTopNtoOptIn() { spawnTimeFromNow := time.Now().Add(time.Hour) powerShapingParams := powerShapingParamsTemplate() initParams := consumerInitParamsTemplate(&spawnTimeFromNow) - proposalMsg := msgCreateConsumer(chainName, initParams, powerShapingParams, nil, chainsuite.GovModuleAddress) - s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), proposalMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + proposalMsg := msgCreateConsumer(chainName, initParams, powerShapingParams, nil, chainsuite.ProviderGovModuleAddress) + s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), proposalMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) consumerChain, err := s.Provider.GetConsumerChainByChainId(s.GetContext(), chainName) s.Require().NoError(err) powerShapingParams.Top_N = 100 initParams.SpawnTime = time.Now().Add(-time.Hour) upgradeMsg := &providertypes.MsgUpdateConsumer{ - Owner: chainsuite.GovModuleAddress, + Owner: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerChain.ConsumerID, - NewOwnerAddress: chainsuite.GovModuleAddress, + NewOwnerAddress: chainsuite.ProviderGovModuleAddress, PowerShapingParameters: powerShapingParams, InitializationParameters: initParams, } - s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) consumerChain, err = s.Provider.GetConsumerChainByChainId(s.GetContext(), chainName) s.Require().NoError(err) s.Require().Equal(providertypes.CONSUMER_PHASE_LAUNCHED.String(), consumerChain.Phase) @@ -397,12 +397,12 @@ func (s *SingleValidatorProviderSuite) TestProviderTransformTopNtoOptIn() { // Transform to opt in chain powerShapingParams.Top_N = 0 upgradeMsg = &providertypes.MsgUpdateConsumer{ - Owner: chainsuite.GovModuleAddress, + Owner: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerChain.ConsumerID, NewOwnerAddress: testAcc, PowerShapingParameters: powerShapingParams, } - s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) optInChain, err := s.Provider.GetConsumerChain(s.GetContext(), consumerChain.ConsumerID) s.Require().NoError(err) s.Require().Equal(powerShapingParams.Top_N, uint32(optInChain.PowerShapingParams.TopN)) @@ -594,10 +594,10 @@ func (s *SingleValidatorProviderSuite) TestProviderOwnerChecks() { // update owner using proposal is not possible - current owner is among expected signers upgradeMsg = &providertypes.MsgUpdateConsumer{ Owner: testAcc2, - NewOwnerAddress: chainsuite.GovModuleAddress, + NewOwnerAddress: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerId, } - err = s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false) + err = s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false) s.Require().Error(err) s.Require().Contains(err.Error(), "expected gov account") @@ -606,17 +606,17 @@ func (s *SingleValidatorProviderSuite) TestProviderOwnerChecks() { // update to top N using proposal upgradeMsg = &providertypes.MsgUpdateConsumer{ - Owner: chainsuite.GovModuleAddress, - NewOwnerAddress: chainsuite.GovModuleAddress, + Owner: chainsuite.ProviderGovModuleAddress, + NewOwnerAddress: chainsuite.ProviderGovModuleAddress, ConsumerId: consumerId, PowerShapingParameters: powerShapingParams, } - s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.GovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) + s.Require().NoError(s.Provider.ExecuteProposalMsg(s.GetContext(), upgradeMsg, chainsuite.ProviderGovModuleAddress, chainName, cosmos.ProposalVoteYes, govv1.StatusPassed, false)) consumerChain, err = s.Provider.GetConsumerChain(s.GetContext(), consumerId) s.Require().NoError(err) s.Require().Equal(providertypes.CONSUMER_PHASE_LAUNCHED.String(), consumerChain.Phase) s.Require().Equal(powerShapingParams.Top_N, uint32(consumerChain.PowerShapingParams.TopN)) - s.Require().Equal(chainsuite.GovModuleAddress, consumerChain.OwnerAddress) + s.Require().Equal(chainsuite.ProviderGovModuleAddress, consumerChain.OwnerAddress) } // Tests adding and updating infraction parameters with MsgCreateConsumer and MsgUpdateConsumer. diff --git a/tests/interchain/provider_suite.go b/tests/interchain/provider_suite.go index 88707609ff..280c34ba7c 100644 --- a/tests/interchain/provider_suite.go +++ b/tests/interchain/provider_suite.go @@ -4,8 +4,10 @@ import ( "context" "cosmos/interchain-security/tests/interchain/chainsuite" "fmt" + "strconv" "sync" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/stretchr/testify/suite" ) @@ -25,7 +27,7 @@ func (s *ProviderSuite) SetupSuite() { s.ctx = ctx // create and start provider chain - s.Provider, err = chainsuite.CreateProviderChain(s.GetContext(), s.T(), chainsuite.GetProviderSpec(s.ValidatorNodes)) + s.Provider, err = chainsuite.CreateChain(s.GetContext(), s.T(), chainsuite.GetProviderSpec(s.ValidatorNodes, providerModifiedGenesis())) s.Require().NoError(err) } @@ -48,3 +50,20 @@ func (s *ProviderSuite) GetUnusedTestingAddresss() (formattedAddress string, key return "", "", fmt.Errorf("no unused wallets available") } + +func providerModifiedGenesis() []cosmos.GenesisKV { + return []cosmos.GenesisKV{ + cosmos.NewGenesisKV("app_state.staking.params.unbonding_time", chainsuite.ProviderUnbondingTime.String()), + cosmos.NewGenesisKV("app_state.gov.params.voting_period", chainsuite.GovVotingPeriod.String()), + cosmos.NewGenesisKV("app_state.gov.params.max_deposit_period", chainsuite.GovDepositPeriod.String()), + cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.denom", chainsuite.Stake), + cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.amount", strconv.Itoa(chainsuite.GovMinDepositAmount)), + cosmos.NewGenesisKV("app_state.slashing.params.signed_blocks_window", strconv.Itoa(chainsuite.ProviderSlashingWindow)), + cosmos.NewGenesisKV("app_state.slashing.params.downtime_jail_duration", chainsuite.DowntimeJailDuration.String()), + cosmos.NewGenesisKV("app_state.slashing.params.slash_fraction_double_sign", chainsuite.SlashFractionDoubleSign), + cosmos.NewGenesisKV("app_state.provider.params.slash_meter_replenish_period", chainsuite.ProviderReplenishPeriod), + cosmos.NewGenesisKV("app_state.provider.params.slash_meter_replenish_fraction", chainsuite.ProviderReplenishFraction), + cosmos.NewGenesisKV("app_state.provider.params.blocks_per_epoch", "1"), + cosmos.NewGenesisKV("app_state.staking.params.max_validators", "1"), + } +} diff --git a/tests/interchain/provider_utils.go b/tests/interchain/provider_utils.go index fb372f3cfc..a6d78f586f 100644 --- a/tests/interchain/provider_utils.go +++ b/tests/interchain/provider_utils.go @@ -36,9 +36,9 @@ func consumerInitParamsTemplate(spawnTime *time.Time) *providertypes.ConsumerIni InitialHeight: clienttypes.NewHeight(1, 1), GenesisHash: []byte("gen_hash"), BinaryHash: []byte("bin_hash"), - UnbondingPeriod: 10 * time.Second, - CcvTimeoutPeriod: time.Duration(100000000000), - TransferTimeoutPeriod: time.Duration(100000000000), + UnbondingPeriod: 1728000000000000, + CcvTimeoutPeriod: 2419200000000000, + TransferTimeoutPeriod: 3600000000000, ConsumerRedistributionFraction: "0.75", BlocksPerDistributionTransmission: 10, HistoricalEntries: 10000, From d5c766a73bbe666f080f8d73bdd5372c5b6d63b2 Mon Sep 17 00:00:00 2001 From: mpoke Date: Thu, 2 Jan 2025 11:46:23 +0100 Subject: [PATCH 13/25] remove setting preccv in app.go --- app/consumer-democracy/app.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index e8903ce78e..ce34dc7170 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -677,7 +677,6 @@ func New( } } - // TODO: remove this code // For a new consumer chain, this code (together with the entire SetUpgradeHandler) is not needed at all, // upgrade handler code is application specific. However, as an example, standalone to consumer // changeover chains should utilize customized upgrade handler code similar to below. @@ -690,8 +689,6 @@ func New( consumerGenesis := consumertypes.GenesisState{} appCodec.MustUnmarshalJSON(appState[consumertypes.ModuleName], &consumerGenesis) - - consumerGenesis.PreCCV = true app.ConsumerKeeper.InitGenesis(sdkCtx, &consumerGenesis) app.Logger().Info("start to run module migrations...") From fad5f5bc5ead89794506e360238998598e512597 Mon Sep 17 00:00:00 2001 From: mpoke Date: Thu, 2 Jan 2025 13:57:08 +0100 Subject: [PATCH 14/25] add todos for genesis transformation --- FEATURES.md | 37 ++++----- RELEASES.md | 19 +++-- app/consumer/genesis.go | 23 +++--- app/consumer/genesis_test.go | 151 ++++++++++++++++++++++++++++++++--- 4 files changed, 185 insertions(+), 45 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index 18808a8b72..d97c3038d7 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -2,22 +2,23 @@ The following table indicates the major ICS features available in the [currently active releases](./RELEASES.md#version-matrix): -| Feature | `v4.0.0` | `v4.4.0` | `v4.5.0` | `v5.0.0` | `v5.2.0` | `v6.1.0` | `v6.3.0` | -|---------|---------:|---------:|---------:|---------:|----------:|---------:|---------:| +| Feature | `v4.0.0` | `v4.4.0` | `v4.5.0` | `v5.0.0` | `v5.2.0` | `v6.1.0` | `v6.3.0` | `v6.4.0` | +|---------|---------:|---------:|---------:|---------:|----------:|---------:|---------:|---------:| | [Channel initialization: new chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-new-chains) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Validator set update](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#validator-set-update) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Completion of unbonding operations](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#completion-of-unbonding-operations) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Consumer initiated slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#consumer-initiated-slashing) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Reward distribution](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Consumer chain removal](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#consumer-chain-removal) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Key assignment](https://github.com/cosmos/interchain-security/issues/26) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling](https://github.com/cosmos/interchain-security/issues/404) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Soft opt-out](https://github.com/cosmos/interchain-security/issues/851) | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | -| [Channel initialization: existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains) (aka [Standalone to consumer changeover](https://github.com/cosmos/interchain-security/issues/756)) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Cryptographic verification of equivocation](https://github.com/cosmos/interchain-security/issues/732) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [ICS epochs](https://cosmos.github.io/interchain-security/adrs/adr-014-epochs) | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Partial Set Security](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security) | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | -| [Inactive Provider Validators](https://cosmos.github.io/interchain-security/adrs/adr-017-allowing-inactive-validators) | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | -| [Permissionless](https://cosmos.github.io/interchain-security/adrs/adr-019-permissionless-ics) | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | -| [ICS Rewards in non-native denoms](https://github.com/cosmos/interchain-security/issues/1634) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | +| [Validator set update](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#validator-set-update) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Completion of unbonding operations](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#completion-of-unbonding-operations) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | +| [Consumer initiated slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#consumer-initiated-slashing) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Reward distribution](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Consumer chain removal](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#consumer-chain-removal) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Key assignment](https://github.com/cosmos/interchain-security/issues/26) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling](https://github.com/cosmos/interchain-security/issues/404) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Soft opt-out](https://github.com/cosmos/interchain-security/issues/851) | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | +| [Channel initialization: existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains) (aka [Standalone to consumer changeover](https://github.com/cosmos/interchain-security/issues/756)) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Cryptographic verification of equivocation](https://github.com/cosmos/interchain-security/issues/732) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [ICS epochs](https://cosmos.github.io/interchain-security/adrs/adr-014-epochs) | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Partial Set Security](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security) | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | +| [Inactive Provider Validators](https://cosmos.github.io/interchain-security/adrs/adr-017-allowing-inactive-validators) | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | +| [Permissionless](https://cosmos.github.io/interchain-security/adrs/adr-019-permissionless-ics) | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | +| [ICS Rewards in non-native denoms](https://github.com/cosmos/interchain-security/issues/1634) | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | +| [Customizable Slashing and Jailing](https://cosmos.github.io/interchain-security/adrs/adr-020-cutomizable_slashing_and_jailing) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | diff --git a/RELEASES.md b/RELEASES.md index 5def947a74..ab4b19a017 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -66,6 +66,7 @@ All missing minor release versions have been discontinued. | `v5.2.x` | May 9, 2025 | | `v6.1.x` | Sep 13, 2025 | | `v6.3.x` | Sep 13, 2025 | +| `v6.4.x` | Sep 13, 2025 | ## Version Matrix @@ -80,6 +81,7 @@ Versions of Golang, IBC, Cosmos SDK and CometBFT used by ICS in the currently ac | [v5.2.0](https://github.com/cosmos/interchain-security/releases/tag/v5.2.0) | 1.22 | v8.3.2 | v0.50.8 | v0.38.9 | | | [v6.1.0](https://github.com/cosmos/interchain-security/releases/tag/v6.1.0) | 1.22 | v8.5.0 | v0.50.9 | v0.38.11 | | | [v6.3.0](https://github.com/cosmos/interchain-security/releases/tag/v6.3.0) | 1.22 | v8.5.1 | v0.50.9 | v0.38.11 | | +| [v6.4.0](https://github.com/cosmos/interchain-security/releases/tag/v6.4.0) | 1.22 | v8.5.2 | v0.50.11 | v0.38.15 | | **Note:** For a list of major ICS features available in the currently active releases, see [FEATURES.md](./FEATURES.md). @@ -89,14 +91,15 @@ A MAJOR version of ICS will always be backwards compatible with the previous MAJ The following table indicates the compatibility of currently active releases: -| Consumer | Provider | `v5.2.0` | `v6.1.0` | `v6.3.0` | -| -------- | -------- | -------- | -------- | -------- | -| `v4.0.0` | | ✅ | ✅ | ✅ (1) | -| `v4.4.0` | | ✅ | ✅ | ✅ (1) | -| `v4.5.0` | | ✅ | ✅ | ✅ | -| `v5.0.0` | | ✅ | ✅ | ✅ (1) | -| `v5.2.0` | | ✅ | ✅ | ✅ (1) | -| `v6.3.0` | | ✅ | ✅ | ✅ | +| Consumer | Provider | `v5.2.0` | `v6.1.0` | `v6.3.0` | `v6.4.0` | +| ------------------- | -------- | -------- | -------- | -------- | -------- | +| `v4.0.0` | | ✅ | ✅ | ✅ (1) | ✅ (1) | +| `v4.4.0` | | ✅ | ✅ | ✅ (1) | ✅ (1) | +| `v4.5.0` | | ✅ | ✅ | ✅ | ✅ (1) | +| `v5.0.0` | | ✅ | ✅ | ✅ (1) | ✅ (1) | +| `v5.2.0` | | ✅ | ✅ | ✅ (1) | ✅ (1) | +| `v6.2.0` / `v6.3.0` | | ✅ | ✅ | ✅ | ✅ (1) | +| `v6.4.0` | | ✅ | ✅ | ✅ | ✅ | #### Notes The following adjustments must be made to the CCV consumer genesis state that is obtained from the provider chain after the spawn time is reached in order for the consumer chain to start without errors. diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index e16c2f4b0e..fea0498ec6 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -31,13 +31,17 @@ type GenesisState map[string]json.RawMessage type IcsVersion string const ( - v4_x_x IcsVersion = "v4.x" - v5_x_x IcsVersion = "v5.x" + v4_x_x IcsVersion = "= v6.2.x // to a format supported by consumer chains version with either SDK v0.47 and ICS < v4.5.0 or SDK v0.50 and ICS < v6.2.0 // This transformation removes the 'consumer_id' parameter from the 'params' field introduced in ICS v6.2.x -func transformToV5(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) { +func removeConsumerID(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) { srcConGen := types.ConsumerGenesisState{} err := ctx.Codec.UnmarshalJSON(jsonRaw, &srcConGen) if err != nil { @@ -100,7 +104,8 @@ func transformGenesis(ctx client.Context, targetVersion IcsVersion, jsonRaw []by switch targetVersion { case v4_x_x, v5_x_x: - newConsumerGenesis, err = transformToV5(jsonRaw, ctx) + newConsumerGenesis, err = removeConsumerID(jsonRaw, ctx) + // TODO: in addition, remove both `connection_id` and `preCCV` fields if target is v4_5_x or v6_x_x default: err = fmt.Errorf("unsupported target version '%s'. Run %s --help", targetVersion, version.AppName) @@ -165,17 +170,17 @@ func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { func GetConsumerGenesisTransformCmd() *cobra.Command { cmd := &cobra.Command{ Use: "transform [-to version] genesis-file", - Short: "Transform CCV consumer genesis data exported to a specific target format", + Short: "Transform consumer module genesis data exported to a specific target format", Long: strings.TrimSpace( fmt.Sprintf(` -Transform the consumer genesis data exported from a provider version v5.x v6.x to a specified consumer target version. +Transform the consumer genesis data exported from a provider version >= v6.3.x to a specified consumer target version. The result is printed to STDOUT. Note: Content to be transformed is not the consumer genesis file itself but the exported content from provider chain which is used to patch the consumer genesis file! Example: $ %s transform /path/to/ccv_consumer_genesis.json -$ %s --to v2.x transform /path/to/ccv_consumer_genesis.json +$ %s --to v5.x transform /path/to/ccv_consumer_genesis.json `, version.AppName, version.AppName), ), Args: cobra.RangeArgs(1, 2), diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index 8c9266f626..2065054471 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -22,15 +22,18 @@ import ( ) const ( - V6x = "v6.x" - V5x = "v5.x" - V4x = "v4.x" + Provider_v6_3_x = "v6.3.x" + Provider_v6_4_x = "v6.4.x" + Consumer_v6_x_x = " Date: Mon, 6 Jan 2025 11:43:18 +0100 Subject: [PATCH 15/25] interchain test desc added to testing.md --- TESTING.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/TESTING.md b/TESTING.md index 4a50f6d3de..a0cea2173b 100644 --- a/TESTING.md +++ b/TESTING.md @@ -44,6 +44,13 @@ Notably, as-of-now simulation tests do not include any multi-chain testing, so c To test compatibility between different provider and consumer versions the [E2E tests](tests/e2e/) were extended by compatibility tests. The test cases perform basic sanity tests against the selected provider and consumer versions. A selected combination of provider and consumer versions are tested on a nightly bases and can be run locally with the related make command listed below. +## Interchain Tests +The interchain tests evaluate the fundamental functionalities of both the provider and provider-consumer chains. This includes testing the transition of a sovereign chain to a consumer chain. These tests leverage the interchain framework, where each chain node operates within its own Docker container.To execute these tests, you can use the default ics image built from the latest code on the main branch. Alternatively, tests can be run with a specific image and version, whether published or locally built. The tests are triggered using the make test-interchain command. For more details, see the [Running Tests](#running-tests) section. +- If you wish to build the docker image from the code on your desired branch, run this command: +```bash + docker build -t test-image:local . +``` + ## Running Tests Tests can be run using `make`: @@ -80,6 +87,11 @@ make sim-full #run simulation tests where providerModule.max_provider_consensus_validators=stakingModule.max_validators=100 make sim-full-no-inactive-vals + +#run interchain tests (running with the latest image ghcr.io/cosmos/interchain-security:latest) +make test-interchain +# run interchain tests with specific image(e.g. test-image:local) +make test-interchain PROVIDER_IMAGE_NAME=test-image PROVIDER_IMAGE_TAG=local SOUVEREIGN_IMAGE_NAME=test-image SOUVEREIGN_IMAGE_TAG=local ``` Alternatively you can run tests using `go test`: From 7deec2d8113bb828f2e5f29def29023e3b93a05c Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Mon, 6 Jan 2025 16:13:16 +0100 Subject: [PATCH 16/25] update genesis transformation --- app/consumer/genesis.go | 65 ++++++++++++++++------------------- app/consumer/genesis_test.go | 66 +++++++++++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 43 deletions(-) diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index fea0498ec6..fb087d7f4e 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -10,12 +10,9 @@ import ( "github.com/spf13/cobra" "golang.org/x/exp/maps" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - - "github.com/cosmos/interchain-security/v6/x/ccv/types" ) // The genesis state of the blockchain is represented here as a map of raw json @@ -60,52 +57,44 @@ func removeParameterFromParams(params json.RawMessage, param string) (json.RawMe // Transformation of consumer genesis content as it is exported by provider version >= v6.2.x // to a format supported by consumer chains version with either SDK v0.47 and ICS < v4.5.0 or SDK v0.50 and ICS < v6.2.0 // This transformation removes the 'consumer_id' parameter from the 'params' field introduced in ICS v6.2.x -func removeConsumerID(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) { - srcConGen := types.ConsumerGenesisState{} - err := ctx.Codec.UnmarshalJSON(jsonRaw, &srcConGen) - if err != nil { - return nil, fmt.Errorf("reading consumer genesis data failed: %s", err) - } - +func removeConsumerID(genState map[string]json.RawMessage) (map[string]json.RawMessage, error) { // Remove 'consumer_id' from 'params' - params, err := ctx.Codec.MarshalJSON(&srcConGen.Params) + params, err := removeParameterFromParams(genState["params"], "consumer_id") if err != nil { return nil, err } - params, err = removeParameterFromParams(params, "consumer_id") - if err != nil { - return nil, err - } - - // Marshal GenesisState and patch 'params' value - result, err := ctx.Codec.MarshalJSON(&srcConGen) - if err != nil { - return nil, err - } - genState := map[string]json.RawMessage{} - if err := json.Unmarshal(result, &genState); err != nil { - return nil, fmt.Errorf("unmarshalling 'GenesisState' failed: %v", err) - } genState["params"] = params - result, err = json.Marshal(genState) - if err != nil { - return nil, fmt.Errorf("marshalling transformation result failed: %v", err) + return genState, nil +} + +func removeFieldsFromGenesisState(genState map[string]json.RawMessage, keysToRemove []string) (map[string]json.RawMessage, error) { + for _, key := range keysToRemove { + delete(genState, key) // Remove the key from the map if it exists } - return result, nil + return genState, nil } // transformGenesis transforms ccv consumer genesis data to the specified target version // Returns the transformed data or an error in case the transformation failed or the format is not supported by current implementation -func transformGenesis(ctx client.Context, targetVersion IcsVersion, jsonRaw []byte) (json.RawMessage, error) { - var newConsumerGenesis json.RawMessage = nil +func transformGenesis(targetVersion IcsVersion, jsonRaw []byte) (json.RawMessage, error) { var err error + // Unmarshal genesis state from raw msg + genState := map[string]json.RawMessage{} + if err := json.Unmarshal(jsonRaw, &genState); err != nil { + return nil, fmt.Errorf("unmarshalling 'GenesisState' failed: %v", err) + } switch targetVersion { case v4_x_x, v5_x_x: - newConsumerGenesis, err = removeConsumerID(jsonRaw, ctx) - // TODO: in addition, remove both `connection_id` and `preCCV` fields if target is v4_5_x or v6_x_x + genState, err = removeConsumerID(genState) + if err != nil { + break + } + genState, err = removeFieldsFromGenesisState(genState, []string{"preCCV", "connection_id"}) + case v4_5_x, v6_x_x: + genState, err = removeFieldsFromGenesisState(genState, []string{"preCCV", "connection_id"}) default: err = fmt.Errorf("unsupported target version '%s'. Run %s --help", targetVersion, version.AppName) @@ -114,6 +103,13 @@ func transformGenesis(ctx client.Context, targetVersion IcsVersion, jsonRaw []by if err != nil { return nil, fmt.Errorf("transformation failed: %v", err) } + + // Marshal genesis state to raw msg + newConsumerGenesis, err := json.Marshal(genState) + if err != nil { + return nil, fmt.Errorf("marshalling transformation result failed: %v", err) + } + return newConsumerGenesis, err } @@ -130,7 +126,6 @@ func TransformConsumerGenesis(cmd *cobra.Command, args []string) error { return err } - clientCtx := client.GetClientContextFromCmd(cmd) version, err := cmd.Flags().GetString("to") if err != nil { return fmt.Errorf("error getting targetVersion %v", err) @@ -141,7 +136,7 @@ func TransformConsumerGenesis(cmd *cobra.Command, args []string) error { } // try to transform data to target format - newConsumerGenesis, err := transformGenesis(clientCtx, targetVersion, jsonRaw) + newConsumerGenesis, err := transformGenesis(targetVersion, jsonRaw) if err != nil { return err } diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index 2065054471..75693faa83 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -275,8 +275,8 @@ var consumerGenesisStates map[string]string = map[string]string{ ] }, "new_chain": true, - "preCCV": false, - "connection_id": "" + "preCCV": true, + "connection_id": "connection-0" } `, } @@ -353,9 +353,25 @@ func TestConsumerGenesisTransformationV63xToV4x(t *testing.T) { CheckGenesisTransform(t, Provider_v6_3_x, Consumer_v4_x_x) } -// TODO: check the following transformations -// - Provider_v6_4_x to Consumer_v4_5_x -// - Provider_v6_4_x to Consumer_v6_x_x +// Check transformation of provider v6.4.x implementation to consumer v4.x.x +func TestConsumerGenesisTransformationV64xToV4xx(t *testing.T) { + CheckGenesisTransform(t, Provider_v6_4_x, Consumer_v4_x_x) +} + +// Check transformation of provider v6.4.x implementation to consumer v5.x.x +func TestConsumerGenesisTransformationV64xToV5xx(t *testing.T) { + CheckGenesisTransform(t, Provider_v6_4_x, Consumer_v5_x_x) +} + +// Check transformation of provider v6.4.x implementation to consumer v4.5.x +func TestConsumerGenesisTransformationV64xToV45x(t *testing.T) { + CheckGenesisTransform(t, Provider_v6_4_x, Consumer_v4_5_x) +} + +// Check transformation of provider v6.4.x implementation to consumer v6.x.x +func TestConsumerGenesisTransformationV64xToV6xx(t *testing.T) { + CheckGenesisTransform(t, Provider_v6_4_x, Consumer_v6_x_x) +} // CheckGenesisTransform checks that the transformation of consumer genesis data // from a given source version to a target version is successful @@ -388,7 +404,14 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str require.NoError(t, err) _, consumerIdFound := params["consumer_id"] - require.False(t, consumerIdFound, "consumer_id field should not be present in params") + require.Equal(t, shouldContainConsumerId(targetVersion), consumerIdFound) + + // Check for preCCV + _, found = resultRaw["preCCV"] + require.Equal(t, shouldContainPreCCVAndConnectionId(targetVersion), found) + // Check for no connection_id + _, found = resultRaw["connection_id"] + require.Equal(t, shouldContainPreCCVAndConnectionId(targetVersion), found) // Iterate over all fields of ConsumerParams and check: // - that they match between source and result genesis @@ -401,9 +424,15 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str srcField := srcParams.Field(i).Interface() // srcType and resultType are the same so we can use index 'i' to get the field from resultParams resultField := resultParams.Field(i).Interface() - if fieldName == "ConsumerId" { + if fieldName == "ConsumerId" && !shouldContainConsumerId(targetVersion) { // ConsumerId is not present in v5.x => expect empty string when unmarshalled to v6 require.EqualValues(t, "", resultField, "Field %s does not match", fieldName) + } else if fieldName == "PreCCV" && !shouldContainPreCCVAndConnectionId(targetVersion) { + // PreCCV is not present in expect false when unmarshalled it + require.EqualValues(t, false, resultField, "Field %s does not match", fieldName) + } else if fieldName == "ConnectionId" && !shouldContainPreCCVAndConnectionId(targetVersion) { + // ConnectionId is not present in expect empty string when unmarshalled it + require.EqualValues(t, "", resultField, "Field %s does not match", fieldName) } else { require.EqualValues(t, srcField, resultField, "Field %s does not match", fieldName) } @@ -419,7 +448,7 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str for i := 0; i < srcParams.NumField(); i++ { fieldName := srcType.Field(i).Name // Skip Params field as it was checked above - if fieldName == "Params" { + if fieldName == "Params" || fieldName == "PreCCV" || fieldName == "ConnectionId" { continue } srcField := srcParams.Field(i).Interface() @@ -428,3 +457,24 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str require.EqualValues(t, srcField, resultField, "Field %s does not match", fieldName) } } + +func shouldContainConsumerId(version string) bool { + switch version { + case Consumer_v6_x_x, Consumer_v4_5_x: + return true + case Consumer_v5_x_x, Consumer_v4_x_x: + return false + } + + return false +} + +func shouldContainPreCCVAndConnectionId(version string) bool { + switch version { + case Consumer_v4_x_x, Consumer_v4_5_x, Consumer_v5_x_x, Consumer_v6_x_x: + return false + // future greater versions will contain this fields and should return true + } + + return false +} From add1b5e80a07dc850d737a428d0173d6a14aae19 Mon Sep 17 00:00:00 2001 From: mpoke Date: Tue, 7 Jan 2025 14:39:36 +0100 Subject: [PATCH 17/25] update changeover procedure docs --- .../changeover-procedure.md | 232 ++++-------------- 1 file changed, 41 insertions(+), 191 deletions(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 17b8faa713..b70b2efb8d 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -4,160 +4,63 @@ sidebar_position: 6 # Changeover Procedure -Chains that were **not** initially launched as consumers of Interchain Security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a replicated consumer chain is called the **changeover procedure** and is part of the interchain security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. +Chains that were **not** initially launched as consumers of Interchain Security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a consumer chain is called the **changeover procedure** and is part of the Interchain Security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. The relevant protocol specifications are available below: * [ICS-28 with existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains). * [ADR in ICS repo](../adrs/adr-010-standalone-changeover.md) -## Overview +## Consumers on ICS Version `v6.4.0+` -Standalone to consumer changeover procedure can roughly be separated into 4 parts: +For chains that are using ICS `v6.4.0` or newer, the standalone to consumer changeover consists of the following steps. -### 1. `MsgCreateConsumer` submitted to the `provider` chain -The `MsgCreateConsumer` is equivalent to the "normal" `MsgCreateConsumer` message submitted by new consumer chains. +### 1. Create a new consumer chain on the provider -However, here are the most important notes and differences between a new consumer chain and a standalone chain performing a changeover: +Submit a `MsgCreateConsumer` message to the provider chain. This is a "normal" [MsgCreateConsumer message](../build/modules/02-provider.md#msgcreateconsumer) as described in the [onboarding checklist](./onboarding.md), but with the following important notes. -* `chain_id` must be equal to the standalone chain id -* `initial_height` field has additional rules to abide by: +* `chain_id` **MUST** be equal to the standalone chain id. +* The consumer initialization parameters (i.e., `initialization_parameters`) must be adapted for the changeover procedure: + + * `initial_height` is not used as the provider uses an existing client of the standalone chain.. + * `spawn_time` is the time on the provider when the consumer module genesis state is being generated, + which means that at this time the provide creates the initial validator set that will validate the standalone chain once it becomes a consumer chain. + Consequently, `spawn_time` **MUST** occur before the standalone chain is upgraded and the consumer module is added as the upgrade requires the consumer module genesis state. + * `unbonding_period` **MUST** correspond to the value used on the standalone chain. + * `distribution_transmission_channel` **SHOULD** be set to the canonical IBC token transfer channel between the provider and the standalone chain. This will preserve the `ibc denom` that may already be in use. + * `connection_id` **MUST** be set to the ID of the connection end on the provider chain on top of which the canonical IBC token transfer channel was created. + +### 2. Add consumer module to standalone chain -:::caution -``` -{ -... - "initial_height" : { - // must correspond to current revision number of standalone chain - // e.g. stride-1 => "revision_number": 1 - "revision_number": 1, +The standalone chain **MUST** go through an upgrade to include the `x/ccv/consumer` module. +Note that adding the `x/ccv/consumer` module requires the consumer module genesis state which is created by the provider at `spawn_time`. +Consequently, the `spawn_time` should occur before this upgrade. - // must correspond to a height that is at least 1 block after the upgrade - // that will add the `consumer` module to the standalone chain - // e.g. "upgrade_height": 100 => "revision_height": 101 - "revision_height": 101, - }, -... -} +Note that the consumer module genesis state can be obtain from the provider using the [consumer genesis query](../build/modules/02-provider.md#consumer-genesis), i.e., +```shell +interchain-security-pd query provider consumer-genesis [consumer-id] [flags] ``` -::: - -* `genesis_hash` can be safely ignored because the chain is already running. A hash of the standalone chain's initial genesis may be used - -* `binary_hash` may not be available ahead of time. All chains performing the changeover go through rigorous testing - if bugs are caught and fixed the hash listed in the proposal may not be the most recent one. - -* `spawn_time` listed in the proposal MUST be before the `upgrade_height` listed in the upgrade proposal on the standalone chain. -:::caution -`spawn_time` must occur before the `upgrade_height` on the standalone chain is reached because the `provider` chain must generate the `ConsumerGenesis` that contains the **validator set** that will be used after the changeover. -::: - -* `unbonding_period` must correspond to the value used on the standalone chain. Otherwise, the clients used for the ccv protocol may be incorrectly initialized. - -* `distribution_transmission_channel` **should be set**. - -:::note -Populating `distribution_transmission_channel` will enable the standalone chain to reuse one of the existing channels to the provider for consumer chain rewards distribution. This will preserve the `ibc denom` that may already be in use. - -If the parameter is not set, a new channel will be created. -::: - -* `ccv_timeout_period` has no important notes - -* `transfer_timeout_period` has no important notes - -* `consumer_redistribution_fraction` has no important notes - -* `blocks_per_distribution_transmission` has no important notes - -* `historical_entries` has no important notes - - -### 2. upgrade proposal on standalone chain - -The standalone chain creates an upgrade proposal to include the `interchain-security/x/ccv/consumer` module. - -:::caution -The upgrade height in the proposal should correspond to a height that is after the `spawn_time` in the `MsgCreateConsumer` submitted to the `provider` chain. -::: - -Otherwise, the upgrade is indistinguishable from a regular on-chain upgrade proposal. - -### 3. spawn time is reached - -When the `spawn_time` is reached on the `provider` it will generate a `ConsumerGenesis` that contains the validator set that will supersede the `standalone` validator set. - -This `ConsumerGenesis` must be available on the standalone chain during the on-chain upgrade. - -### 4. standalone chain upgrade - -Performing the on-chain upgrade on the standalone chain will add the `ccv/consumer` module and allow the chain to become a `consumer` of Interchain Security. - -:::caution -The `ConsumerGenesis` must be exported to a file and placed in the correct folder on the standalone chain before the upgrade. +The consumer genesis state must be exported to a file and placed in the correct folder on the standalone chain before the upgrade. The file must be placed at the exact specified location, otherwise the upgrade will not be executed correctly. +Usually the file is placed in `$NODE_HOME/config`, but the file name and the exact directory is dictated by the upgrade code on the `standalone` chain. +Please check exact instructions provided by the `standalone` chain team. -Usually the file is placed in `$NODE_HOME/config`, but the file name and the exact directory is dictated by the upgrade code on the `standalone` chain. -* please check exact instructions provided by the `standalone` chain team -::: - -After the `genesis.json` file has been made available, the process is equivalent to a normal on-chain upgrade. The standalone validator set will sign the next couple of blocks before transferring control to `provider` validator set. - -The standalone validator set can still be slashed for any infractions if evidence is submitted within the `unboding_period`. - -#### Notes - -The changeover procedure may be updated in the future to create a seamless way of providing the validator set information to the standalone chain. - -## Onboarding Checklist - -This onboarding checklist is slightly different from the one under [Onboarding](./onboarding.md) - -Additionally, you can check the [testnet repo](https://github.com/cosmos/testnets/blob/master/interchain-security/CONSUMER_LAUNCH_GUIDE.md) for a comprehensive guide on preparing and launching consumer chains. - -## 1. Complete testing & integration - -- [ ] test integration with gaia -- [ ] test your protocol with supported relayer versions (minimum hermes 1.4.1) -- [ ] test the changeover procedure -- [ ] reach out to the ICS team if you are facing issues +After the `genesis.json` file has been made available, the process is equivalent to a normal on-chain upgrade. The standalone validator set will sign the next couple of blocks before transferring control to the initial ICS validator set. -## 2. Create an Onboarding Repository +Once upgraded, the `x/ccv/consumer` module will act as the "staking module" for the consumer chain, i.e., it will provide the validator set to the consensus engine. For staking a native token (e.g., for governance), the `x/ccv/democracy/staking` module allows the cosmos-sdk `x/staking` module to be used alongside the `x/ccv/consumer` module. For more details, check out the [democracy modules](../build/modules/04-democracy.md). -To help validators and other node runners onboard onto your chain, please prepare a repository with information on how to run your chain. +## Consumers on ICS Version `< v6.4.0` -This should include (at minimum): +Chains that are using older version of ICS (i.e., `< v6.4.0`), must "force" the provider to create a new client of the standalone chain (on top of which the CCV channel will be created). +This is because older versions of the consumer module expects both a client state and a consensus state in order to create a new provider client. +Therefore, when creating a new consumer chain on the provider, the following changes are necessary in the consumer initialization parameters: -- [ ] genesis.json with CCV data (after spawn time passes). Check if CCV data needs to be transformed (see [Transform Consumer Genesis](./consumer-genesis-transformation.md)) -- [ ] information about relevant seed/peer nodes you are running -- [ ] relayer information (compatible versions) -- [ ] copy of your governance proposal (as JSON) -- [ ] a script showing how to start your chain and connect to peers (optional) -- [ ] take feedback from other developers, validators and community regarding your onboarding repo and make improvements where applicable - -Example of such a repository can be found [here](https://github.com/hyphacoop/ics-testnets/tree/main/game-of-chains-2022/sputnik). - -## 3. Submit a `MsgCreateConsumer` to the provider - -Before you submit a `MsgCreateConsumer` message, please provide a `spawn_time` that is **before** the `upgrade_height` of the upgrade that will introduce the `ccv module` to your chain. -:::danger -If the `spawn_time` happens after your `upgrade_height` the provider will not be able to communicate the new validator set to be used after the changeover. -::: - -Additionally, reach out to the community via the [forum](https://forum.cosmos.network/) to formalize your intention to become an ICS consumer, gather community support and accept feedback from the community, validators and developers. - -- [ ] determine your chain's spawn time -- [ ] determine consumer chain parameters to be put in the proposal -- [ ] take note to include a link to your onboarding repository - -Example of initialization parameters (compare with the [those](./onboarding.md#3-submit-msgcreateconsumer-and-msgupdateconsumer-messages) for chains that *launch* as consumers): - -```js -// ConsumerInitializationParameters provided in MsgCreateConsumer or MsgUpdateConsumer -{ - // Initial height of new consumer chain. +* `connection_id` **MUST** be set to an empty string (i.e., `""`). As a result, the provider will create a new client of the consumer chain and a new connection on top of it. +* `initial_height` will be used by the provider when creating the new consumer client, so it **MUST** be set according to the following rules: + ```json "initial_height" : { // must correspond to current revision number of standalone chain - // e.g. standalone-1 => "revision_number": 1 + // e.g. stride-1 => "revision_number": 1 "revision_number": 1, // must correspond to a height that is at least 1 block after the upgrade @@ -165,65 +68,12 @@ Example of initialization parameters (compare with the [those](./onboarding.md# // e.g. "upgrade_height": 100 => "revision_height": 101 "revision_height": 101, }, - // Hash of the consumer chain genesis state without the consumer CCV module genesis params. - // => not relevant for changeover procedure - "genesis_hash": "d86d756e10118e66e6805e9cc476949da2e750098fcc7634fd0cc77f57a0b2b0", - // Hash of the consumer chain binary that should be run by validators on standalone chain upgrade - // => not relevant for changeover procedure as it may become stale - "binary_hash": "376cdbd3a222a3d5c730c9637454cd4dd925e2f9e2e0d0f3702fc922928583f1", - // Time on the provider chain at which the consumer chain genesis is finalized and all validators - // will be responsible for starting their consumer chain validator node. - "spawn_time": "2023-02-28T20:40:00.000000Z", - // Unbonding period for the consumer chain. - // It should should be smaller than that of the provider. - "unbonding_period": 1728000000000000, - // Timeout period for CCV related IBC packets. - // Packets are considered timed-out after this interval elapses. - "ccv_timeout_period": 2419200000000000, - // IBC transfer packets will timeout after this interval elapses. - "transfer_timeout_period": 1800000000000, - // The fraction of tokens allocated to the consumer redistribution address during distribution events. - // The fraction is a string representing a decimal number. For example "0.75" would represent 75%. - // The reward amount distributed to the provider is calculated as: 1 - consumer_redistribution_fraction. - "consumer_redistribution_fraction": "0.75", - // BlocksPerDistributionTransmission is the number of blocks between IBC token transfers from the consumer chain to the provider chain. - // eg. send rewards to the provider every 1000 blocks - "blocks_per_distribution_transmission": 1000, - // The number of historical info entries to persist in store. - // This param is a part of the cosmos sdk staking module. In the case of - // a ccv enabled consumer chain, the ccv module acts as the staking module. - "historical_entries": 10000, - // The ID of a token transfer channel used for the Reward Distribution - // sub-protocol. If DistributionTransmissionChannel == "", a new transfer - // channel is created on top of the same connection as the CCV channel. - // Note that transfer_channel_id is the ID of the channel end on the consumer chain. - // it is most relevant for chains performing a standalone to consumer changeover - // in order to maintain the existing ibc transfer channel - "distribution_transmission_channel": "channel-123" // NOTE: use existing transfer channel if available -} -``` - -:::info -The changeover procedure can be used together with [Partial Set Security](../adrs/adr-015-partial-set-security.md). -This means, that a standalone chain can choose to only be validated by some of the validators of the provider chain by setting `top_N` appropriately, or by -additionally setting a validators-power cap, validator-set cap, etc. by using the [power-shaping parameters](../features/power-shaping.md). -::: - -## 3. Submit an Upgrade Proposal & Prepare for Changeover - -This proposal should add the ccv `consumer` module to your chain. - -- [ ] proposal `upgrade_height` must happen after `spawn_time` in the `MsgCreateConsumer` -- [ ] advise validators about the exact procedure for your chain and point them to your onboarding repository - + ``` -## 4. Upgrade time 🚀 +### Adapt the consumer module genesis state -- [ ] after `spawn_time`, request `ConsumerGenesis` from the `provider` and place it in `/.sovereign/config/genesis.json` -- [ ] upgrade the binary to the one listed in your `UpgradeProposal` +Before the upgrade of the standalone chain (i.e., adding the `x/ccv/consumer` module), the consumer module genesis state created by the provider at `spawn_time` must be adapted to older versions of the consumer module. This consists of two changes. -The chain starts after at least 66.67% of standalone voting power comes online. The consumer chain is considered interchain secured once the "old" validator set signs a couple of blocks and transfers control to the `provider` validator set. +First, by setting `connection_id` to an empty string, the provider will set the `preCCV` flag in the `ConsumerGenesisState` struct to `false`. This must be change to `true` in order to trigger the changeover procedure logic on the `x/ccv/consumer` module. -- [ ] provide a repo with onboarding instructions for validators (it should already be listed in the proposal) -- [ ] genesis.json after `spawn_time` obtained from `provider` (MUST contain the initial validator set) -- [ ] maintenance & emergency contact info (relevant discord, telegram, slack or other communication channels) +Second, the `connection_id` field of `ConsumerGenesisState` must be removed to enable older versions of the consumer module to unmarshal the consumer module genesis state obtained from the provider. This can be done using the `interchain-security-cd genesis transform` CLI command. \ No newline at end of file From 1dc3ea13411769afc6a1cb511f6d4ee45f916c2d Mon Sep 17 00:00:00 2001 From: Marius Poke Date: Tue, 7 Jan 2025 17:12:18 +0100 Subject: [PATCH 18/25] Update docs/docs/consumer-development/changeover-procedure.md Co-authored-by: MSalopek --- docs/docs/consumer-development/changeover-procedure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index b70b2efb8d..2758a4390a 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -33,7 +33,7 @@ Submit a `MsgCreateConsumer` message to the provider chain. This is a "normal" [ The standalone chain **MUST** go through an upgrade to include the `x/ccv/consumer` module. Note that adding the `x/ccv/consumer` module requires the consumer module genesis state which is created by the provider at `spawn_time`. -Consequently, the `spawn_time` should occur before this upgrade. +Consequently, the `spawn_time` **MUST** occur before this upgrade. Note that the consumer module genesis state can be obtain from the provider using the [consumer genesis query](../build/modules/02-provider.md#consumer-genesis), i.e., ```shell From 75a982678be3771886544ede5ec748fe32e0dccd Mon Sep 17 00:00:00 2001 From: Marius Poke Date: Tue, 7 Jan 2025 17:12:28 +0100 Subject: [PATCH 19/25] Update docs/docs/consumer-development/changeover-procedure.md Co-authored-by: MSalopek --- docs/docs/consumer-development/changeover-procedure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 2758a4390a..c2ae8eb51e 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -35,7 +35,7 @@ The standalone chain **MUST** go through an upgrade to include the `x/ccv/consum Note that adding the `x/ccv/consumer` module requires the consumer module genesis state which is created by the provider at `spawn_time`. Consequently, the `spawn_time` **MUST** occur before this upgrade. -Note that the consumer module genesis state can be obtain from the provider using the [consumer genesis query](../build/modules/02-provider.md#consumer-genesis), i.e., +Note that the consumer module genesis state can be obtained from the provider using the [consumer genesis query](../build/modules/02-provider.md#consumer-genesis), i.e., ```shell interchain-security-pd query provider consumer-genesis [consumer-id] [flags] ``` From c061b27a2cc605c37e296741906b5d57a9551427 Mon Sep 17 00:00:00 2001 From: Marius Poke Date: Tue, 7 Jan 2025 17:12:39 +0100 Subject: [PATCH 20/25] Update docs/docs/consumer-development/changeover-procedure.md Co-authored-by: MSalopek --- docs/docs/consumer-development/changeover-procedure.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index c2ae8eb51e..660ec2b35d 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -43,7 +43,6 @@ interchain-security-pd query provider consumer-genesis [consumer-id] [flags] The consumer genesis state must be exported to a file and placed in the correct folder on the standalone chain before the upgrade. The file must be placed at the exact specified location, otherwise the upgrade will not be executed correctly. Usually the file is placed in `$NODE_HOME/config`, but the file name and the exact directory is dictated by the upgrade code on the `standalone` chain. -Please check exact instructions provided by the `standalone` chain team. After the `genesis.json` file has been made available, the process is equivalent to a normal on-chain upgrade. The standalone validator set will sign the next couple of blocks before transferring control to the initial ICS validator set. From 88f24ea7b07da176bab3e863f44f5e6bdc9be947 Mon Sep 17 00:00:00 2001 From: Marius Poke Date: Tue, 7 Jan 2025 17:12:55 +0100 Subject: [PATCH 21/25] Update docs/docs/consumer-development/changeover-procedure.md Co-authored-by: MSalopek --- docs/docs/consumer-development/changeover-procedure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 660ec2b35d..ab91cec19f 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -44,7 +44,7 @@ The consumer genesis state must be exported to a file and placed in the correct The file must be placed at the exact specified location, otherwise the upgrade will not be executed correctly. Usually the file is placed in `$NODE_HOME/config`, but the file name and the exact directory is dictated by the upgrade code on the `standalone` chain. -After the `genesis.json` file has been made available, the process is equivalent to a normal on-chain upgrade. The standalone validator set will sign the next couple of blocks before transferring control to the initial ICS validator set. +After the `consumer_genesis.json` file has been made available, the process is equivalent to a normal on-chain upgrade. The standalone validator set will sign the next couple of blocks before transferring control to the initial ICS validator set. Once upgraded, the `x/ccv/consumer` module will act as the "staking module" for the consumer chain, i.e., it will provide the validator set to the consensus engine. For staking a native token (e.g., for governance), the `x/ccv/democracy/staking` module allows the cosmos-sdk `x/staking` module to be used alongside the `x/ccv/consumer` module. For more details, check out the [democracy modules](../build/modules/04-democracy.md). From 0c378eb14ddb834595a3e79007400805a52f3936 Mon Sep 17 00:00:00 2001 From: Marius Poke Date: Tue, 7 Jan 2025 17:13:10 +0100 Subject: [PATCH 22/25] Update docs/docs/consumer-development/changeover-procedure.md Co-authored-by: MSalopek --- docs/docs/consumer-development/changeover-procedure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index ab91cec19f..9b4736dfdd 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -73,6 +73,6 @@ Therefore, when creating a new consumer chain on the provider, the following cha Before the upgrade of the standalone chain (i.e., adding the `x/ccv/consumer` module), the consumer module genesis state created by the provider at `spawn_time` must be adapted to older versions of the consumer module. This consists of two changes. -First, by setting `connection_id` to an empty string, the provider will set the `preCCV` flag in the `ConsumerGenesisState` struct to `false`. This must be change to `true` in order to trigger the changeover procedure logic on the `x/ccv/consumer` module. +First, by setting `connection_id` to an empty string, the provider will set the `preCCV` flag in the `ConsumerGenesisState` struct to `false`. This must be changed to `true` in order to trigger the changeover procedure logic on the `x/ccv/consumer` module. Second, the `connection_id` field of `ConsumerGenesisState` must be removed to enable older versions of the consumer module to unmarshal the consumer module genesis state obtained from the provider. This can be done using the `interchain-security-cd genesis transform` CLI command. \ No newline at end of file From 015037d7f6da328f99fdf75a9acec44336073297 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 7 Jan 2025 17:19:25 +0100 Subject: [PATCH 23/25] tests: remove unused e2e changeover [replaced by interchaintest] --- tests/e2e/action_rapid_test.go | 45 -- tests/e2e/actions.go | 107 --- tests/e2e/actions_sovereign_chain.go | 198 ------ tests/e2e/json_utils.go | 24 - tests/e2e/main.go | 6 - tests/e2e/steps.go | 15 - tests/e2e/steps_sovereign_changeover.go | 371 ---------- tests/e2e/test_driver.go | 12 - tests/e2e/testlib/types.go | 14 - .../testnet-scripts/sovereign-genesis.json | 315 --------- tests/e2e/testnet-scripts/start-changeover.sh | 189 ----- tests/e2e/testnet-scripts/start-sovereign.sh | 133 ---- tests/e2e/trace_handlers_test.go | 2 - .../e2e/tracehandler_testdata/changeover.json | 659 ------------------ tests/e2e/v5/actions.go | 127 ---- 15 files changed, 2217 deletions(-) delete mode 100644 tests/e2e/actions_sovereign_chain.go delete mode 100644 tests/e2e/steps_sovereign_changeover.go delete mode 100644 tests/e2e/testnet-scripts/sovereign-genesis.json delete mode 100644 tests/e2e/testnet-scripts/start-changeover.sh delete mode 100644 tests/e2e/testnet-scripts/start-sovereign.sh delete mode 100644 tests/e2e/tracehandler_testdata/changeover.json diff --git a/tests/e2e/action_rapid_test.go b/tests/e2e/action_rapid_test.go index dffa0286a8..64bd78a5a7 100644 --- a/tests/e2e/action_rapid_test.go +++ b/tests/e2e/action_rapid_test.go @@ -56,10 +56,6 @@ func MarshalAndUnmarshalAction(action interface{}) error { // include generators for all actions that are mentioned in main.go/runStep. func GetActionGen() *rapid.Generator[any] { return rapid.OneOf( - GetStartSovereignChainActionGen().AsAny(), - GetSubmitLegacyUpgradeProposalActionGen().AsAny(), - GetWaitUntilBlockActionGen().AsAny(), - GetChangeoverChainActionGen().AsAny(), GetSendTokensActionGen().AsAny(), GetStartChainActionGen().AsAny(), GetSubmitTextProposalActionGen().AsAny(), @@ -154,47 +150,6 @@ func GetCreateIbcClientsActionGen() *rapid.Generator[CreateIbcClientsAction] { }) } -func GetStartSovereignChainActionGen() *rapid.Generator[StartSovereignChainAction] { - return rapid.Custom(func(t *rapid.T) StartSovereignChainAction { - return StartSovereignChainAction{ - Chain: GetChainIDGen().Draw(t, "Chain"), - Validators: GetStartChainValidatorsGen().Draw(t, "Validators"), - GenesisChanges: rapid.String().Draw(t, "GenesisChanges"), - } - }) -} - -func GetSubmitLegacyUpgradeProposalActionGen() *rapid.Generator[UpgradeProposalAction] { - return rapid.Custom(func(t *rapid.T) UpgradeProposalAction { - return UpgradeProposalAction{ - ChainID: GetChainIDGen().Draw(t, "ChainID"), - UpgradeTitle: rapid.String().Draw(t, "UpgradeTitle"), - Proposer: GetValidatorIDGen().Draw(t, "Proposer"), - UpgradeHeight: rapid.Uint64().Draw(t, "UpgradeHeight"), - } - }) -} - -func GetWaitUntilBlockActionGen() *rapid.Generator[WaitUntilBlockAction] { - return rapid.Custom(func(t *rapid.T) WaitUntilBlockAction { - return WaitUntilBlockAction{ - Chain: GetChainIDGen().Draw(t, "Chain"), - Block: rapid.Uint().Draw(t, "Block"), - } - }) -} - -func GetChangeoverChainActionGen() *rapid.Generator[ChangeoverChainAction] { - return rapid.Custom(func(t *rapid.T) ChangeoverChainAction { - return ChangeoverChainAction{ - SovereignChain: GetChainIDGen().Draw(t, "SovereignChain"), - ProviderChain: GetChainIDGen().Draw(t, "ProviderChain"), - Validators: GetStartChainValidatorsGen().Draw(t, "Validators"), - GenesisChanges: rapid.String().Draw(t, "GenesisChanges"), - } - }) -} - func GetSendTokensActionGen() *rapid.Generator[SendTokensAction] { return rapid.Custom(func(t *rapid.T) SendTokensAction { return SendTokensAction{ diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 588a1c5d56..7aefcf7460 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -38,12 +38,10 @@ type ( StartChainAction = e2e.StartChainAction StartChainValidator = e2e.StartChainValidator StartConsumerChainAction = e2e.StartConsumerChainAction - StartSovereignChainAction = e2e.StartSovereignChainAction SubmitConsumerAdditionProposalAction = e2e.SubmitConsumerAdditionProposalAction SubmitConsumerRemovalProposalAction = e2e.SubmitConsumerRemovalProposalAction DelegateTokensAction = e2e.DelegateTokensAction UnbondTokensAction = e2e.UnbondTokensAction - ChangeoverChainAction = e2e.ChangeoverChainAction ) type SendTokensAction struct { @@ -1100,111 +1098,6 @@ func (tr *Chain) transformConsumerGenesis(targetVersion string, genesis []byte) return result } -func (tr Chain) changeoverChain( - action e2e.ChangeoverChainAction, - verbose bool, -) { - consumerGenesis := ".app_state.ccvconsumer = " + tr.getConsumerGenesis(action.ProviderChain, action.SovereignChain) - - consumerGenesisChanges := tr.testConfig.ChainConfigs[action.SovereignChain].GenesisChanges - if consumerGenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges - } - if action.GenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + action.GenesisChanges - } - - tr.startChangeover(e2e.ChangeoverChainAction{ - Validators: action.Validators, - GenesisChanges: consumerGenesis, - }, verbose) -} - -func (tr Chain) startChangeover( - action e2e.ChangeoverChainAction, - verbose bool, -) { - chainConfig := tr.testConfig.ChainConfigs[ChainID("sover")] - type jsonValAttrs struct { - Mnemonic string `json:"mnemonic"` - Allocation string `json:"allocation"` - Stake string `json:"stake"` - ValId string `json:"val_id"` - PrivValidatorKey string `json:"priv_validator_key"` - NodeKey string `json:"node_key"` - IpSuffix string `json:"ip_suffix"` - - ConsumerMnemonic string `json:"consumer_mnemonic"` - ConsumerPrivValidatorKey string `json:"consumer_priv_validator_key"` - StartWithConsumerKey bool `json:"start_with_consumer_key"` - } - - var validators []jsonValAttrs - for _, val := range action.Validators { - validators = append(validators, jsonValAttrs{ - Mnemonic: tr.testConfig.ValidatorConfigs[val.Id].Mnemonic, - NodeKey: tr.testConfig.ValidatorConfigs[val.Id].NodeKey, - ValId: fmt.Sprint(val.Id), - PrivValidatorKey: tr.testConfig.ValidatorConfigs[val.Id].PrivValidatorKey, - Allocation: fmt.Sprint(val.Allocation) + "stake", - Stake: fmt.Sprint(val.Stake) + "stake", - IpSuffix: tr.testConfig.ValidatorConfigs[val.Id].IpSuffix, - - ConsumerMnemonic: tr.testConfig.ValidatorConfigs[val.Id].ConsumerMnemonic, - ConsumerPrivValidatorKey: tr.testConfig.ValidatorConfigs[val.Id].ConsumerPrivValidatorKey, - // if true node will be started with consumer key for each consumer chain - StartWithConsumerKey: tr.testConfig.ValidatorConfigs[val.Id].UseConsumerKey, - }) - } - - vals, err := json.Marshal(validators) - if err != nil { - log.Fatal(err) - } - - // Concat genesis changes defined in chain config, with any custom genesis changes for this chain instantiation - var genesisChanges string - if action.GenesisChanges != "" { - genesisChanges = chainConfig.GenesisChanges + " | " + action.GenesisChanges - } else { - genesisChanges = chainConfig.GenesisChanges - } - - isConsumer := true - changeoverScript := tr.target.GetTestScriptPath(isConsumer, "start-changeover.sh") - cmd := tr.target.ExecCommand( - "/bin/bash", - changeoverScript, chainConfig.UpgradeBinary, string(vals), - "sover", chainConfig.IpPrefix, genesisChanges, - tr.testConfig.TendermintConfigOverride, - ) - - cmdReader, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - cmd.Stderr = cmd.Stdout - - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - - scanner := bufio.NewScanner(cmdReader) - - for scanner.Scan() { - out := scanner.Text() - if verbose { - fmt.Println("startChangeover: " + out) - } - if out == done { - break - } - } - if err := scanner.Err(); err != nil { - log.Fatal("startChangeover died", err) - } -} - type AddChainToRelayerAction struct { Chain ChainID Validator ValidatorID diff --git a/tests/e2e/actions_sovereign_chain.go b/tests/e2e/actions_sovereign_chain.go deleted file mode 100644 index a9d9f861e0..0000000000 --- a/tests/e2e/actions_sovereign_chain.go +++ /dev/null @@ -1,198 +0,0 @@ -package main - -import ( - "bufio" - "encoding/json" - "fmt" - "log" - "time" - - e2e "github.com/cosmos/interchain-security/v6/tests/e2e/testlib" -) - -// calls a simplified startup script (start-sovereign.sh) and runs a validator node -// upgrades are simpler with a single validator node since only one node needs to be upgraded -func (tr Chain) startSovereignChain( - action e2e.StartSovereignChainAction, - verbose bool, -) { - chainConfig := tr.testConfig.ChainConfigs["sover"] - type jsonValAttrs struct { - Mnemonic string `json:"mnemonic"` - Allocation string `json:"allocation"` - Stake string `json:"stake"` - ValId string `json:"val_id"` - PrivValidatorKey string `json:"priv_validator_key"` - NodeKey string `json:"node_key"` - IpSuffix string `json:"ip_suffix"` - - ConsumerMnemonic string `json:"consumer_mnemonic"` - ConsumerPrivValidatorKey string `json:"consumer_priv_validator_key"` - StartWithConsumerKey bool `json:"start_with_consumer_key"` - } - - var validators []jsonValAttrs - for _, val := range action.Validators { - validators = append(validators, jsonValAttrs{ - Mnemonic: tr.testConfig.ValidatorConfigs[val.Id].Mnemonic, - NodeKey: tr.testConfig.ValidatorConfigs[val.Id].NodeKey, - ValId: fmt.Sprint(val.Id), - PrivValidatorKey: tr.testConfig.ValidatorConfigs[val.Id].PrivValidatorKey, - Allocation: fmt.Sprint(val.Allocation) + "stake", - Stake: fmt.Sprint(val.Stake) + "stake", - IpSuffix: tr.testConfig.ValidatorConfigs[val.Id].IpSuffix, - - ConsumerMnemonic: tr.testConfig.ValidatorConfigs[val.Id].ConsumerMnemonic, - ConsumerPrivValidatorKey: tr.testConfig.ValidatorConfigs[val.Id].ConsumerPrivValidatorKey, - // if true node will be started with consumer key for each consumer chain - StartWithConsumerKey: tr.testConfig.ValidatorConfigs[val.Id].UseConsumerKey, - }) - } - - vals, err := json.Marshal(validators) - if err != nil { - log.Fatal(err) - } - - // Concat genesis changes defined in chain config, with any custom genesis changes for this chain instantiation - var genesisChanges string - if action.GenesisChanges != "" { - genesisChanges = chainConfig.GenesisChanges + " | " + action.GenesisChanges - } else { - genesisChanges = chainConfig.GenesisChanges - } - - isConsumer := chainConfig.BinaryName != "interchain-security-pd" - testScriptPath := tr.target.GetTestScriptPath(isConsumer, "start-sovereign.sh") - cmd := tr.target.ExecCommand("/bin/bash", testScriptPath, chainConfig.BinaryName, string(vals), - string(chainConfig.ChainId), chainConfig.IpPrefix, genesisChanges, - tr.testConfig.TendermintConfigOverride) - - cmdReader, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - cmd.Stderr = cmd.Stdout - - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - - scanner := bufio.NewScanner(cmdReader) - - for scanner.Scan() { - out := scanner.Text() - if verbose { - fmt.Println("startSovereignChain: " + out) - } - if out == done { - break - } - } - if err := scanner.Err(); err != nil { - log.Fatal(err) - } - tr.addChainToRelayer(AddChainToRelayerAction{ - Chain: action.Chain, - Validator: action.Validators[0].Id, - }, verbose) -} - -type UpgradeProposalAction struct { - ChainID ChainID - UpgradeTitle string - Proposer ValidatorID - UpgradeHeight uint64 - Expedited bool -} - -func (tr *Chain) submitUpgradeProposal(action UpgradeProposalAction, verbose bool) { - // Get authority address - binary := tr.testConfig.ChainConfigs[ChainID("sover")].BinaryName - cmd := tr.target.ExecCommand(binary, - "query", "upgrade", "authority", - "--node", tr.getValidatorNode(ChainID("sover"), action.Proposer), - "-o", "json") - bz, err := cmd.CombinedOutput() - if err != nil { - log.Fatalf("failed running command '%s': %v", cmd, err) - } - - var authority struct { - Address string `json:"address"` - } - err = json.Unmarshal(bz, &authority) - if err != nil { - log.Fatalf("Failed getting authority: err=%v, data=%s", err, string(bz)) - } - - // Upgrade Proposal Content - metadata := "ipfs://CID" - deposit := "10000000stake" - summary := "my summary" - proposalJson := fmt.Sprintf(` -{ - "messages": [ - { - "@type": "/cosmos.upgrade.v1beta1.MsgSoftwareUpgrade", - "authority": "%s", - "plan": { - "name": "sovereign-changeover", - "height": "%d", - "info": "my upgrade info", - "upgraded_client_state": null - } - } - ], - "metadata": "%s", - "title": "%s", - "summary": "%s", - "deposit": "%s", - "expedited": %t -}`, authority.Address, action.UpgradeHeight, metadata, action.UpgradeTitle, summary, deposit, action.Expedited) - - //#nosec G204 -- bypass unsafe quoting warning (no production code) - proposalPath := "/temp-proposal.json" - bz, err = tr.target.ExecCommand( - "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, proposalJson, proposalPath), - ).CombinedOutput() - if err != nil { - log.Fatal(err, "\n", string(bz)) - } - - // Submit Proposal - cmd = tr.target.ExecCommand(binary, - "tx", "gov", "submit-proposal", proposalPath, - "--gas", "900000", - "--from", "validator"+string(action.Proposer), - "--keyring-backend", "test", - "--chain-id", string(tr.testConfig.ChainConfigs[ChainID("sover")].ChainId), - "--home", tr.getValidatorHome(ChainID("sover"), action.Proposer), - "--node", tr.getValidatorNode(ChainID("sover"), action.Proposer), - "-y") - - if verbose { - fmt.Println("Submit proposal:", cmd.String()) - } - - bz, err = cmd.CombinedOutput() - if err != nil { - log.Fatal(err, "\n", string(bz)) - } - if verbose { - log.Println("Response to submit-proposal: ", string(bz)) - } - - tr.waitBlocks(action.ChainID, 1, 15*time.Second) -} - -type WaitUntilBlockAction struct { - Block uint - Chain ChainID -} - -func (tr *Chain) waitUntilBlockOnChain(action WaitUntilBlockAction) { - fmt.Println("waitUntilBlockOnChain is waiting for block:", action.Block) - tr.waitUntilBlock(action.Chain, action.Block, 120*time.Second) - fmt.Println("waitUntilBlockOnChain done waiting for block:", action.Block) -} diff --git a/tests/e2e/json_utils.go b/tests/e2e/json_utils.go index be82e9f45a..c25944a866 100644 --- a/tests/e2e/json_utils.go +++ b/tests/e2e/json_utils.go @@ -216,30 +216,6 @@ func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string if err == nil { return a, nil } - case "main.LegacyUpgradeProposalAction": - var a UpgradeProposalAction - err := json.Unmarshal(rawAction, &a) - if err == nil { - return a, nil - } - case "main.WaitUntilBlockAction": - var a WaitUntilBlockAction - err := json.Unmarshal(rawAction, &a) - if err == nil { - return a, nil - } - case "main.ChangeoverChainAction": - var a ChangeoverChainAction - err := json.Unmarshal(rawAction, &a) - if err == nil { - return a, nil - } - case "main.StartSovereignChainAction": - var a StartSovereignChainAction - err := json.Unmarshal(rawAction, &a) - if err == nil { - return a, nil - } case "main.LightClientEquivocationAttackAction": var a LightClientEquivocationAttackAction err := json.Unmarshal(rawAction, &a) diff --git a/tests/e2e/main.go b/tests/e2e/main.go index bc060ae905..0f935e0ee1 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -103,12 +103,6 @@ var stepChoices = map[string]StepChoice{ description: "happy path tests", testConfig: DefaultTestCfg, }, - "changeover": { - name: "changeover", - steps: changeoverSteps, - description: "changeover tests", - testConfig: ChangeoverTestCfg, - }, "democracy-reward": { name: "democracy-reward", steps: democracyRegisteredDenomSteps, diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index b9b635452f..a776d41bd8 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -107,21 +107,6 @@ var multipleConsumers = concatSteps( stepsMultiConsumerDoubleSign("consu", "densu"), // double sign on one of the chains ) -var changeoverSteps = concatSteps( - // start sovereign chain and test delegation operation - - stepRunSovereignChain(), - stepStartProviderChain(), - stepsSovereignTransferChan(), - - // the chain will halt once upgrade height is reached - // after upgrade height is reached, the chain will become a consumer - stepsUpgradeChain(), - stepsChangeoverToConsumer("sover"), - - stepsPostChangeoverDelegate("sover"), -) - var consumerMisbehaviourSteps = concatSteps( // start provider and consumer chain stepsStartChainsForConsumerMisbehaviour("consu"), diff --git a/tests/e2e/steps_sovereign_changeover.go b/tests/e2e/steps_sovereign_changeover.go deleted file mode 100644 index 23d595b8d4..0000000000 --- a/tests/e2e/steps_sovereign_changeover.go +++ /dev/null @@ -1,371 +0,0 @@ -package main - -import ( - gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" -) - -// this creates new clients on both chains and a connection (connection-0) between them -// connection-0 is used to create a transfer channel between the chains -// the transfer channel is maintained during the changeover process, meaning that -// the consumer chain will be able to send rewards to the provider chain using the old channel -// as opposed to creating a new transfer channel which happens for new consumers -func stepsSovereignTransferChan() []Step { - return []Step{ - { - Action: CreateIbcClientsAction{ - ChainA: ChainID("sover"), - ChainB: ChainID("provi"), - }, - State: State{}, - }, - { - // this will create channel-0 connection end on both chain - Action: AddIbcChannelAction{ - ChainA: ChainID("sover"), - ChainB: ChainID("provi"), - ConnectionA: 0, - PortA: "transfer", - PortB: "transfer", - Order: "unordered", - Version: "ics20-1", - }, - State: State{}, - }, - } -} - -// steps to convert sovereign to consumer chain -func stepsChangeoverToConsumer(consumerName string) []Step { - s := []Step{ - { - Action: SubmitConsumerAdditionProposalAction{ - PreCCV: true, - Chain: ChainID("provi"), - From: ValidatorID("alice"), - Deposit: 10000001, - ConsumerChain: ChainID(consumerName), - // chain-0 is the transfer channelID that gets created in stepsSovereignTransferChan - // the consumer chain will use this channel to send rewards to the provider chain - // there is no need to create a new channel for rewards distribution - DistributionChannel: "channel-0", - SpawnTime: 0, - InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, // 1 block after upgrade !important - TopN: 100, - }, - State: State{ - ChainID("provi"): ChainState{ - ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9489999999, - ValidatorID("bob"): 9500000000, - }, - Proposals: &map[uint]Proposal{ - 1: ConsumerAdditionProposal{ - Deposit: 10000001, - Chain: ChainID(consumerName), - SpawnTime: 0, - InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, - Status: gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD.String(), - }, - }, - }, - }, - }, - { - Action: VoteGovProposalAction{ - Chain: ChainID("provi"), - From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, - Vote: []string{"yes", "yes", "yes"}, - PropNumber: 1, - }, - State: State{ - ChainID("provi"): ChainState{ - Proposals: &map[uint]Proposal{ - 1: ConsumerAdditionProposal{ - Deposit: 10000001, - Chain: ChainID(consumerName), - SpawnTime: 0, - InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, - Status: gov.ProposalStatus_PROPOSAL_STATUS_PASSED.String(), - }, - }, - ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9500000000, - ValidatorID("bob"): 9500000000, - }, - }, - }, - }, - { - Action: ChangeoverChainAction{ - SovereignChain: ChainID(consumerName), - ProviderChain: ChainID("provi"), - Validators: []StartChainValidator{ - {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, - {Id: ValidatorID("bob"), Stake: 500000000, Allocation: 10000000000}, - {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, - }, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 500, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // uses val powers from consumer - ValidatorID("alice"): 500, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: AddIbcConnectionAction{ - ChainA: ChainID(consumerName), - ChainB: ChainID("provi"), - ClientA: 1, - ClientB: 1, - }, - State: State{}, - }, - { - Action: AddIbcChannelAction{ - ChainA: ChainID(consumerName), - ChainB: ChainID("provi"), - ConnectionA: 1, - PortA: "consumer", - PortB: "provider", - Order: "ordered", - }, - State: State{}, - }, - } - - return s -} - -// start sovereign chain with a single validator so it is easier to manage -// when the chain is converted to a consumer chain the validators from the -// consumer chain will be used -// validatoralice is the only validator on the sovereign chain that is in both -// sovereign validator set and consumer validator set -func stepRunSovereignChain() []Step { - return []Step{ - { - Action: StartSovereignChainAction{ - Chain: ChainID("sover"), - Validators: []StartChainValidator{ - {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, - }, - }, - State: State{ - ChainID("sover"): ChainState{ - ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9500000000, - }, - }, - }, - }, - { - Action: DelegateTokensAction{ - Chain: ChainID("sover"), - From: ValidatorID("alice"), - To: ValidatorID("alice"), - Amount: 11000000, - }, - State: State{ - ChainID("sover"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 0, // does not exist on pre-ccv sover - ValidatorID("carol"): 0, // does not exist on pre-ccv sover - }, - }, - }, - }, - } -} - -// TODO: use args instead of hardcoding -func stepsUpgradeChain() []Step { - return []Step{ - { - Action: UpgradeProposalAction{ - ChainID: ChainID("sover"), - UpgradeTitle: "sovereign-changeover", - Proposer: ValidatorID("alice"), - UpgradeHeight: 110, - Expedited: false, - }, - State: State{ - ChainID("sover"): ChainState{ - Proposals: &map[uint]Proposal{ - 1: UpgradeProposal{ - Title: "sovereign-changeover", - UpgradeHeight: 110, - Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", - Deposit: 10000000, - Status: gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD.String(), - }, - }, - }, - }, - }, - { - Action: VoteGovProposalAction{ - Chain: ChainID("sover"), - From: []ValidatorID{ValidatorID("alice")}, - Vote: []string{"yes"}, - PropNumber: 1, - }, - State: State{ - ChainID("sover"): ChainState{ - Proposals: &map[uint]Proposal{ - 1: UpgradeProposal{ - Deposit: 10000000, - UpgradeHeight: 110, - Title: "sovereign-changeover", - Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", - Status: gov.ProposalStatus_PROPOSAL_STATUS_PASSED.String(), - }, - }, - }, - }, - }, - { - Action: WaitUntilBlockAction{ - Chain: ChainID("sover"), - Block: 110, - }, - State: State{}, - }, - } -} - -// stepsPostChangeoverDelegate tests basic delegation and resulting validator power changes after changeover -// we cannot use stepsDelegate and stepsUnbond because they make assumptions about which connection to use -// here we need to use connection-1, and in tests with new consumers connection-0 is used because the chain is new (has no IBC states prior to launch) -func stepsPostChangeoverDelegate(consumerName string) []Step { - return []Step{ - { - Action: SendTokensAction{ - Chain: ChainID(consumerName), - From: ValidatorID("alice"), - To: ValidatorID("bob"), - Amount: 100, - }, - State: State{ - ChainID(consumerName): ChainState{ - // Tx should not go through, ICS channel is not setup until first VSC packet has been relayed to consumer - ValBalances: &map[ValidatorID]uint{ - ValidatorID("bob"): 0, - }, - }, - }, - }, - { - Action: DelegateTokensAction{ - Chain: ChainID("provi"), - From: ValidatorID("alice"), - To: ValidatorID("alice"), - Amount: 11000000, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 500, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 1, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: SendTokensAction{ - Chain: ChainID(consumerName), - From: ValidatorID("alice"), - To: ValidatorID("bob"), - Amount: 100, - }, - State: State{ - ChainID(consumerName): ChainState{ - // Tx should go through, ICS channel is setup - ValBalances: &map[ValidatorID]uint{ - ValidatorID("bob"): 100, - }, - }, - }, - }, - { - Action: UnbondTokensAction{ - Chain: ChainID("provi"), - UnbondFrom: ValidatorID("alice"), - Sender: ValidatorID("alice"), - Amount: 1000000, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 510, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Voting power on consumer should not be affected yet - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 1, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 510, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - } -} diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index 3b918912ae..d3ed0be9e4 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -297,18 +297,6 @@ func (td *DefaultDriver) runAction(action interface{}) error { case StartChainAction: target := td.getTargetDriver(action.Chain) target.StartChain(action, td.verbose) - case StartSovereignChainAction: - target := td.getTargetDriver(action.Chain) - target.startSovereignChain(action, td.verbose) - case UpgradeProposalAction: - target := td.getTargetDriver(ChainID("sover")) - target.submitUpgradeProposal(action, td.verbose) - case WaitUntilBlockAction: - target := td.getTargetDriver(action.Chain) - target.waitUntilBlockOnChain(action) - case e2e.ChangeoverChainAction: - target := td.getTargetDriver("") - target.changeoverChain(action, td.verbose) case SendTokensAction: target := td.getTargetDriver(action.Chain) target.sendTokens(action, td.verbose) diff --git a/tests/e2e/testlib/types.go b/tests/e2e/testlib/types.go index f5fce3df09..6a290a2483 100644 --- a/tests/e2e/testlib/types.go +++ b/tests/e2e/testlib/types.go @@ -76,20 +76,6 @@ type StartConsumerChainAction struct { GenesisChanges string } -type ChangeoverChainAction struct { - SovereignChain ChainID - ProviderChain ChainID - Validators []StartChainValidator - GenesisChanges string -} - -type StartSovereignChainAction struct { - Chain ChainID - Validators []StartChainValidator - // Genesis changes specific to this action, appended to genesis changes defined in chain config - GenesisChanges string -} - type DelegateTokensAction struct { Chain ChainID From ValidatorID diff --git a/tests/e2e/testnet-scripts/sovereign-genesis.json b/tests/e2e/testnet-scripts/sovereign-genesis.json deleted file mode 100644 index bf7c881b1d..0000000000 --- a/tests/e2e/testnet-scripts/sovereign-genesis.json +++ /dev/null @@ -1,315 +0,0 @@ -{ - "genesis_time": "2023-06-22T15:55:00.982713586Z", - "chain_id": "sover", - "initial_height": "1", - "consensus_params": { - "block": { - "max_bytes": "22020096", - "max_gas": "-1" - }, - "evidence": { - "max_age_num_blocks": "100000", - "max_age_duration": "172800000000000", - "max_bytes": "1048576" - }, - "validator": { - "pub_key_types": [ - "ed25519" - ] - }, - "version": { - "app": "0" - } - }, - "app_hash": "", - "app_state": { - "07-tendermint": null, - "auth": { - "params": { - "max_memo_characters": "256", - "tx_sig_limit": "7", - "tx_size_cost_per_byte": "10", - "sig_verify_cost_ed25519": "590", - "sig_verify_cost_secp256k1": "1000" - }, - "accounts": [ - { - "@type": "/cosmos.auth.v1beta1.BaseAccount", - "address": "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", - "pub_key": null, - "account_number": "0", - "sequence": "0" - } - ] - }, - "authz": { - "authorization": [] - }, - "bank": { - "params": { - "send_enabled": [], - "default_send_enabled": true - }, - "balances": [ - { - "address": "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", - "coins": [ - { - "denom": "stake", - "amount": "10000000000" - } - ] - } - ], - "supply": [ - { - "denom": "stake", - "amount": "10000000000" - } - ], - "denom_metadata": [], - "send_enabled": [] - }, - "capability": { - "index": "1", - "owners": [] - }, - "crisis": { - "constant_fee": { - "denom": "stake", - "amount": "1000" - } - }, - "distribution": { - "params": { - "community_tax": "0.020000000000000000", - "base_proposer_reward": "0.000000000000000000", - "bonus_proposer_reward": "0.000000000000000000", - "withdraw_addr_enabled": true - }, - "fee_pool": { - "community_pool": [] - }, - "delegator_withdraw_infos": [], - "previous_proposer": "", - "outstanding_rewards": [], - "validator_accumulated_commissions": [], - "validator_historical_rewards": [], - "validator_current_rewards": [], - "delegator_starting_infos": [], - "validator_slash_events": [] - }, - "evidence": { - "evidence": [] - }, - "feegrant": { - "allowances": [] - }, - "genutil": { - "gen_txs": [ - { - "body": { - "messages": [ - { - "@type": "/cosmos.staking.v1beta1.MsgCreateValidator", - "description": { - "moniker": "validatoralice", - "identity": "", - "website": "", - "security_contact": "", - "details": "" - }, - "commission": { - "rate": "0.100000000000000000", - "max_rate": "0.200000000000000000", - "max_change_rate": "0.010000000000000000" - }, - "min_self_delegation": "1", - "delegator_address": "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", - "validator_address": "consumervaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddy6jwzg", - "pubkey": { - "@type": "/cosmos.crypto.ed25519.PubKey", - "key": "RrclQz9bIhkIy/gfL485g3PYMeiIku4qeo495787X10=" - }, - "value": { - "denom": "stake", - "amount": "500000000" - } - } - ], - "memo": "8339e14baab81c2a2350e261962263397a8d7fb0@7.7.7.254:26656", - "timeout_height": "0", - "extension_options": [], - "non_critical_extension_options": [] - }, - "auth_info": { - "signer_infos": [ - { - "public_key": { - "@type": "/cosmos.crypto.secp256k1.PubKey", - "key": "AsFC8tmbGGQSHthsVStbsQ13/+Yza9IT8KCSXXEN7y9f" - }, - "mode_info": { - "single": { - "mode": "SIGN_MODE_DIRECT" - } - }, - "sequence": "0" - } - ], - "fee": { - "amount": [], - "gas_limit": "200000", - "payer": "", - "granter": "" - }, - "tip": null - }, - "signatures": [ - "AZROMEeaBL9cDOWQJYYdAG3KDl+w37SK0XP88ecS+WwQQLj8rXuEKNDl1PXpZR0AFIJ8coSwhFEtbpV44j6uVQ==" - ] - } - ] - }, - "gov": { - "starting_proposal_id": "1", - "deposits": [], - "votes": [], - "proposals": [], - "deposit_params": null, - "voting_params": null, - "tally_params": null, - "params": { - "min_deposit": [ - { - "denom": "stake", - "amount": "10000000" - } - ], - "max_deposit_period": "172800s", - "voting_period": "20s", - "quorum": "0.334000000000000000", - "threshold": "0.500000000000000000", - "veto_threshold": "0.334000000000000000", - "min_initial_deposit_ratio": "0.000000000000000000", - "proposal_cancel_ratio": "0.500000000000000000", - "proposal_cancel_dest": "", - "expedited_voting_period": "10s", - "expedited_threshold": "0.667000000000000000", - "expedited_min_deposit": [ - { - "denom": "stake", - "amount": "50000000" - } - ], - "burn_vote_quorum": false, - "burn_proposal_deposit_prevote": false, - "burn_vote_veto": true, - "min_deposit_ratio": "0.010000000000000000" - } - }, - "ibc": { - "client_genesis": { - "clients": [], - "clients_consensus": [], - "clients_metadata": [], - "params": { - "allowed_clients": [ - "06-solomachine", - "07-tendermint", - "09-localhost" - ] - }, - "create_localhost": false, - "next_client_sequence": "0" - }, - "connection_genesis": { - "connections": [], - "client_connection_paths": [], - "next_connection_sequence": "0", - "params": { - "max_expected_time_per_block": "30000000000" - } - }, - "channel_genesis": { - "channels": [], - "acknowledgements": [], - "commitments": [], - "receipts": [], - "send_sequences": [], - "recv_sequences": [], - "ack_sequences": [], - "next_channel_sequence": "0", - "params": { - "upgrade_timeout": { - "height": { - "revision_number": "0", - "revision_height": "0" - }, - "timestamp": "600000000000" - } - } - } - }, - "mint": { - "minter": { - "inflation": "0.130000000000000000", - "annual_provisions": "0.000000000000000000" - }, - "params": { - "mint_denom": "stake", - "inflation_rate_change": "0.130000000000000000", - "inflation_max": "0.200000000000000000", - "inflation_min": "0.070000000000000000", - "goal_bonded": "0.670000000000000000", - "blocks_per_year": "6311520" - } - }, - "params": null, - "provider": { - "params": { - "slash_meter_replenish_fraction": "1.0", - "slash_meter_replenish_period": "3s" - } - }, - "slashing": { - "params": { - "signed_blocks_window": "10", - "min_signed_per_window": "0.500000000000000000", - "downtime_jail_duration": "60s", - "slash_fraction_double_sign": "0.050000000000000000", - "slash_fraction_downtime": "0.010000000000000000" - }, - "signing_infos": [], - "missed_blocks": [] - }, - "staking": { - "params": { - "unbonding_time": "1814400s", - "max_validators": 100, - "max_entries": 7, - "historical_entries": 10000, - "bond_denom": "stake", - "min_commission_rate": "0.000000000000000000" - }, - "last_total_power": "0", - "last_validator_powers": [], - "validators": [], - "delegations": [], - "unbonding_delegations": [], - "redelegations": [], - "exported": false - }, - "transfer": { - "port_id": "transfer", - "denom_traces": [], - "params": { - "send_enabled": true, - "receive_enabled": true - }, - "total_escrowed": [] - }, - "upgrade": {}, - "vesting": {} - } -} \ No newline at end of file diff --git a/tests/e2e/testnet-scripts/start-changeover.sh b/tests/e2e/testnet-scripts/start-changeover.sh deleted file mode 100644 index 6a134ac4dc..0000000000 --- a/tests/e2e/testnet-scripts/start-changeover.sh +++ /dev/null @@ -1,189 +0,0 @@ -#!/bin/bash -set -eux - -# The gaiad binary -BIN=$1 - -# JSON array of validator information -# [{ -# mnemonic: "crackle snap pop ... etc", -# allocation: "10000000000stake,10000000000footoken", -# stake: "5000000000stake", -# val_id: "alice", -# ip_suffix: "1", -# priv_validator_key: "{\"address\": \"3566F464673B2F069758DAE86FC25D04017BB147\",\"pub_key\": {\"type\": \"tendermint/PubKeyEd25519\",\"value\": \"XrLjKdc4mB2gfqplvnoySjSJq2E90RynUwaO3WhJutk=\"},\"priv_key\": {\"type\": \"tendermint/PrivKeyEd25519\",\"value\": \"czGSLs/Ocau8aJ5J5zQHMxf3d7NR0xjMECN6YGTIWqtesuMp1ziYHaB+qmW+ejJKNImrYT3RHKdTBo7daEm62Q==\"}}" -# node_key: "{\"priv_key\":{\"type\":\"tendermint/PrivKeyEd25519\",\"value\":\"alIHj6hXnzpLAadgb7+E2eeecwxoNdzuZrfhMX36EaD5/LgzL0ZUoVp7AK3np0K5T35JWLLv0jJKmeRIhG0GjA==\"}}" -# }, ... ] -VALIDATORS=$2 - -# The chain ID -CHAIN_ID=$3 - -# This is the first 3 fields of the IP addresses which will be used internally by the validators of this blockchain -# Recommended to use something starting with 7, since it is squatted by the DoD and is unroutable on the internet -# For example: "7.7.7" -CHAIN_IP_PREFIX=$4 - -# A transformation to apply to the genesis file, as a jq string -GENESIS_TRANSFORM=$5 - -# A sed string modifying the tendermint config -TENDERMINT_CONFIG_TRANSFORM=$6 - - -# CREATE VALIDATORS AND DO GENESIS CEREMONY -# !!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!! # -# data dir from the sovereign chain is copied to other nodes (namely bob and carol) -# alice simply performs a chain upgrade -echo "killing nodes" -pkill -f "^"interchain-security-sd &> /dev/null || true - -# Get number of nodes from length of validators array -NODES=$(echo "$VALIDATORS" | jq '. | length') - -for i in $(seq 0 $(($NODES - 1))); -do - VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") - mkdir -p /$CHAIN_ID/validator$VAL_ID/.sovereign/config - # apply genesis changes to existing genesis -> this creates the changeover genesis file with initial validator set - jq "$GENESIS_TRANSFORM" /sover/validatoralice/config/genesis.json > /$CHAIN_ID/validator$VAL_ID/.sovereign/config/genesis.json -done - -# SETUP NETWORK NAMESPACES, see: https://adil.medium.com/container-networking-under-the-hood-network-namespaces-6b2b8fe8dc2a - -# Create virtual bridge device (acts like a switch) -ip link add name virtual-bridge type bridge || true - -for i in $(seq 0 $(($NODES - 1))); -do - # first validator is already setup - if [[ "$i" -ne 0 ]]; then - VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") - VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$i].ip_suffix") - NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" - IP_ADDR="$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX/24" - - # Create network namespace - ip netns add $NET_NAMESPACE_NAME - # Create virtual ethernet device to connect with bridge - ip link add $NET_NAMESPACE_NAME-in type veth peer name $NET_NAMESPACE_NAME-out - # Connect input end of virtual ethernet device to namespace - ip link set $NET_NAMESPACE_NAME-in netns $NET_NAMESPACE_NAME - # Assign ip address to namespace - ip netns exec $NET_NAMESPACE_NAME ip addr add $IP_ADDR dev $NET_NAMESPACE_NAME-in - # Connect output end of virtual ethernet device to bridge - ip link set $NET_NAMESPACE_NAME-out master virtual-bridge - fi -done - -# Enable bridge interface -ip link set virtual-bridge up - -for i in $(seq 0 $(($NODES - 1))); -do - # first validator is already setup - if [[ "$i" -ne 0 ]]; then - VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") - NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" - - # Enable in/out interfaces for the namespace - ip link set $NET_NAMESPACE_NAME-out up - ip netns exec $NET_NAMESPACE_NAME ip link set dev $NET_NAMESPACE_NAME-in up - # Enable loopback device - ip netns exec $NET_NAMESPACE_NAME ip link set dev lo up - fi -done - -# Assign IP for bridge, to route between default network namespace and bridge -# BRIDGE_IP="$CHAIN_IP_PREFIX.254/24" -# ip addr add $BRIDGE_IP dev virtual-bridge - - -# HANDLE VALIDATOR HOMES, COPY OLD DATA FOLDER -for i in $(seq 0 $(($NODES - 1))); -do - # first validator is already setup - if [[ "$i" -ne 0 ]]; then - VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") - echo "$VALIDATORS" | jq -r ".[$i].mnemonic" | $BIN keys add validator$VAL_ID \ - --home /$CHAIN_ID/validator$VAL_ID \ - --keyring-backend test \ - --recover > /dev/null - - # Copy in the genesis.json - cp /sover/validatoralice/config/genesis.json /$CHAIN_ID/validator$VAL_ID/config/genesis.json - cp -r /sover/validatoralice/data /$CHAIN_ID/validator$VAL_ID/ - - # Copy in validator state file - # echo '{"height": "0","round": 0,"step": 0}' > /$CHAIN_ID/validator$VAL_ID/data/priv_validator_state.json - - - PRIV_VALIDATOR_KEY=$(echo "$VALIDATORS" | jq -r ".[$i].priv_validator_key") - if [[ "$PRIV_VALIDATOR_KEY" ]]; then - echo "$PRIV_VALIDATOR_KEY" > /$CHAIN_ID/validator$VAL_ID/config/priv_validator_key.json - fi - - NODE_KEY=$(echo "$VALIDATORS" | jq -r ".[$i].node_key") - if [[ "$NODE_KEY" ]]; then - echo "$NODE_KEY" > /$CHAIN_ID/validator$VAL_ID/config/node_key.json - fi - - # Modify tendermint configs of validator - if [ "$TENDERMINT_CONFIG_TRANSFORM" != "" ] ; then - #'s/foo/bar/;s/abc/def/' - sed -i "$TENDERMINT_CONFIG_TRANSFORM" $CHAIN_ID/validator$VAL_ID/config/config.toml - fi - fi -done - - -# START VALIDATOR NODES -> this will perform the sovereign upgrade and start the chain -# ALICE is a validator on the sovereign and also the validator on the consumer chain -# BOB, CAROL are not validators on the sovereign, they will become validator once the chain switches to the consumer chain -echo "Starting validator nodes..." -for i in $(seq 0 $(($NODES - 1))); -do - VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$i].val_id") - VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$i].ip_suffix") - NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" - - GAIA_HOME="--home /$CHAIN_ID/validator$VAL_ID" - RPC_ADDRESS="--rpc.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" - GRPC_ADDRESS="--grpc.address $CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:9091" - LISTEN_ADDRESS="--address tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26655" - P2P_ADDRESS="--p2p.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26656" - # LOG_LEVEL="--log_level trace" # switch to trace to see panic messages and rich and all debug msgs - LOG_LEVEL="--log_level info" - ENABLE_WEBGRPC="--grpc-web.enable=false" - - PERSISTENT_PEERS="" - - for j in $(seq 0 $(($NODES - 1))); - do - if [ $i -ne $j ]; then - PEER_VAL_ID=$(echo "$VALIDATORS" | jq -r ".[$j].val_id") - PEER_VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[$j].ip_suffix") - NODE_ID=$($BIN tendermint show-node-id --home /$CHAIN_ID/validator$PEER_VAL_ID) - ADDRESS="$NODE_ID@$CHAIN_IP_PREFIX.$PEER_VAL_IP_SUFFIX:26656" - # (jq -r '.body.memo' /$CHAIN_ID/validator$j/config/gentx/*) # Getting the address from the gentx should also work - PERSISTENT_PEERS="$PERSISTENT_PEERS,$ADDRESS" - fi - done - - # Remove leading comma and concat to flag - PERSISTENT_PEERS="--p2p.persistent_peers ${PERSISTENT_PEERS:1}" - - ARGS="$GAIA_HOME $LISTEN_ADDRESS $RPC_ADDRESS $GRPC_ADDRESS $LOG_LEVEL $P2P_ADDRESS $ENABLE_WEBGRPC $PERSISTENT_PEERS" - ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_ID/logs & -done - -QUERY_NODE_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") -echo "NODE SUFFIX: $QUERY_NODE_SUFFIX" -# poll for chain start -set +e -until $BIN query block --type=height 0 --node "tcp://$CHAIN_IP_PREFIX.$QUERY_NODE_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done -set -e - -echo "done!!!!!!!!" - -read -p "Press Return to Close..." diff --git a/tests/e2e/testnet-scripts/start-sovereign.sh b/tests/e2e/testnet-scripts/start-sovereign.sh deleted file mode 100644 index 54e14dfcf3..0000000000 --- a/tests/e2e/testnet-scripts/start-sovereign.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/bash -set -eux - -# The gaiad binary -BIN=$1 - -# JSON array of validator information -# [{ -# mnemonic: "crackle snap pop ... etc", -# allocation: "10000000000stake,10000000000footoken", -# stake: "5000000000stake", -# val_id: "alice", -# ip_suffix: "1", -# priv_validator_key: "{\"address\": \"3566F464673B2F069758DAE86FC25D04017BB147\",\"pub_key\": {\"type\": \"tendermint/PubKeyEd25519\",\"value\": \"XrLjKdc4mB2gfqplvnoySjSJq2E90RynUwaO3WhJutk=\"},\"priv_key\": {\"type\": \"tendermint/PrivKeyEd25519\",\"value\": \"czGSLs/Ocau8aJ5J5zQHMxf3d7NR0xjMECN6YGTIWqtesuMp1ziYHaB+qmW+ejJKNImrYT3RHKdTBo7daEm62Q==\"}}" -# node_key: "{\"priv_key\":{\"type\":\"tendermint/PrivKeyEd25519\",\"value\":\"alIHj6hXnzpLAadgb7+E2eeecwxoNdzuZrfhMX36EaD5/LgzL0ZUoVp7AK3np0K5T35JWLLv0jJKmeRIhG0GjA==\"}}" -# }, ... ] -VALIDATORS=$2 - -# The chain ID -CHAIN_ID=$3 - -# This is the first 3 fields of the IP addresses which will be used internally by the validators of this blockchain -# Recommended to use something starting with 7, since it is squatted by the DoD and is unroutable on the internet -# For example: "7.7.7" -CHAIN_IP_PREFIX=$4 - -# A transformation to apply to the genesis file, as a jq string -GENESIS_TRANSFORM=$5 - -# A sed string modifying the tendermint config -TENDERMINT_CONFIG_TRANSFORM=$6 - -# SETUP NETWORK NAMESPACES, see: https://adil.medium.com/container-networking-under-the-hood-network-namespaces-6b2b8fe8dc2a - -# Create virtual bridge device (acts like a switch) -ip link add name virtual-bridge type bridge || true - -# used globally in the whole script -VAL_ID=$(echo "$VALIDATORS" | jq -r ".[0].val_id") -VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") -NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" -IP_ADDR="$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX/24" - -# Create network namespace -ip netns add $NET_NAMESPACE_NAME -# Create virtual ethernet device to connect with bridge -ip link add $NET_NAMESPACE_NAME-in type veth peer name $NET_NAMESPACE_NAME-out -# Connect input end of virtual ethernet device to namespace -ip link set $NET_NAMESPACE_NAME-in netns $NET_NAMESPACE_NAME -# Assign ip address to namespace -ip netns exec $NET_NAMESPACE_NAME ip addr add $IP_ADDR dev $NET_NAMESPACE_NAME-in -# Connect output end of virtual ethernet device to bridge -ip link set $NET_NAMESPACE_NAME-out master virtual-bridge - -# Enable bridge interface -ip link set virtual-bridge up - -NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" -# Enable in/out interfaces for the namespace -ip link set $NET_NAMESPACE_NAME-out up -ip netns exec $NET_NAMESPACE_NAME ip link set dev $NET_NAMESPACE_NAME-in up -# Enable loopback device -ip netns exec $NET_NAMESPACE_NAME ip link set dev lo up - -# Assign IP for bridge, to route between default network namespace and bridge -BRIDGE_IP="$CHAIN_IP_PREFIX.254/24" -ip addr add $BRIDGE_IP dev virtual-bridge - -# first we start a genesis.json with the first validator -# the first validator will also collect the gentx's once generated -echo "$VALIDATORS" | jq -r ".[0].mnemonic" | $BIN init --home /$CHAIN_ID/validator$VAL_ID --chain-id=$CHAIN_ID validator$VAL_ID --recover > /dev/null - -# !!!!!!!!! IMPORTANT !!!!!!!!! # -# move the sovereign genesis to the correct validator home dir -cp /testnet-scripts/sovereign-genesis.json /$CHAIN_ID/validator$VAL_ID/config/genesis.json - -# Apply jq transformations to genesis file -jq "$GENESIS_TRANSFORM" /$CHAIN_ID/validator$VAL_ID/config/genesis.json > /$CHAIN_ID/edited-genesis.json -mv /$CHAIN_ID/edited-genesis.json /$CHAIN_ID/genesis.json -cp /$CHAIN_ID/genesis.json /$CHAIN_ID/validator$VAL_ID/config/genesis.json - - - -# SETUP LOCAL VALIDATOR STATE -echo '{"height": "0","round": 0,"step": 0}' > /$CHAIN_ID/validator$VAL_ID/data/priv_validator_state.json - -PRIV_VALIDATOR_KEY=$(echo "$VALIDATORS" | jq -r ".[0].priv_validator_key") -if [[ "$PRIV_VALIDATOR_KEY" ]]; then - echo "$PRIV_VALIDATOR_KEY" > /$CHAIN_ID/validator$VAL_ID/config/priv_validator_key.json -fi - -NODE_KEY=$(echo "$VALIDATORS" | jq -r ".[0].node_key") -if [[ "$NODE_KEY" ]]; then - echo "$NODE_KEY" > /$CHAIN_ID/validator$VAL_ID/config/node_key.json -fi - -echo "$VALIDATORS" | jq -r ".[0].mnemonic" | $BIN keys add validator$VAL_ID \ ---home /$CHAIN_ID/validator$VAL_ID \ ---keyring-backend test \ ---recover > /dev/null - -# Modify tendermint configs of validator -if [ "$TENDERMINT_CONFIG_TRANSFORM" != "" ] ; then - #'s/foo/bar/;s/abc/def/' - sed -i "$TENDERMINT_CONFIG_TRANSFORM" $CHAIN_ID/validator$VAL_ID/config/config.toml -fi - - -# START VALIDATOR NODE -VAL_IP_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") -NET_NAMESPACE_NAME="$CHAIN_ID-$VAL_ID" - -GAIA_HOME="--home /$CHAIN_ID/validator$VAL_ID" -RPC_ADDRESS="--rpc.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" -GRPC_ADDRESS="--grpc.address $CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:9091" -LISTEN_ADDRESS="--address tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26655" -P2P_ADDRESS="--p2p.laddr tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26656" -# LOG_LEVEL="--log_level trace" # switch to trace to see panic messages and rich and all debug msgs -LOG_LEVEL="--log_level info" -ENABLE_WEBGRPC="--grpc-web.enable=false" - -ARGS="$GAIA_HOME $LISTEN_ADDRESS $RPC_ADDRESS $GRPC_ADDRESS $LOG_LEVEL $P2P_ADDRESS $ENABLE_WEBGRPC" -ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_ID/logs & - - -# poll for chain start -set +e -until $BIN query block --type=height 0 --node "tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done -set -e - -echo "done!!!!!!!!" - -read -p "Press Return to Close..." \ No newline at end of file diff --git a/tests/e2e/trace_handlers_test.go b/tests/e2e/trace_handlers_test.go index fe15656545..77e5d83814 100644 --- a/tests/e2e/trace_handlers_test.go +++ b/tests/e2e/trace_handlers_test.go @@ -51,7 +51,6 @@ func TestWriterThenParser(t *testing.T) { "multipleConsumers": {multipleConsumers}, "shorthappy": {shortHappyPathSteps}, "democracyRewardsSteps": {democracyRegisteredDenomSteps}, - "changeover": {changeoverSteps}, } dir, err := os.MkdirTemp("", "example") @@ -82,7 +81,6 @@ func TestWriteExamples(t *testing.T) { "multipleConsumers": {multipleConsumers}, "shorthappy": {shortHappyPathSteps}, "democracyRewardsSteps": {democracyRegisteredDenomSteps}, - "changeover": {changeoverSteps}, "consumer-misbehaviour": {consumerMisbehaviourSteps}, "consumer-double-sign": {consumerDoubleSignSteps}, } diff --git a/tests/e2e/tracehandler_testdata/changeover.json b/tests/e2e/tracehandler_testdata/changeover.json deleted file mode 100644 index af1f68a91a..0000000000 --- a/tests/e2e/tracehandler_testdata/changeover.json +++ /dev/null @@ -1,659 +0,0 @@ -[ - { - "ActionType": "main.StartSovereignChainAction", - "Action": { - "Chain": "sover", - "Validators": [ - { - "Id": "alice", - "Allocation": 10000000000, - "Stake": 500000000 - } - ], - "GenesisChanges": "" - }, - "State": { - "sover": { - "ValBalances": { - "alice": 9500000000 - }, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.DelegateTokensAction", - "Action": { - "Chain": "sover", - "From": "alice", - "To": "alice", - "Amount": 11000000 - }, - "State": { - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 511, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.StartChainAction", - "Action": { - "Chain": "provi", - "Validators": [ - { - "Id": "bob", - "Allocation": 10000000000, - "Stake": 500000000 - }, - { - "Id": "alice", - "Allocation": 10000000000, - "Stake": 500000000 - }, - { - "Id": "carol", - "Allocation": 10000000000, - "Stake": 500000000 - } - ], - "GenesisChanges": "", - "IsConsumer": false - }, - "State": { - "provi": { - "ValBalances": { - "alice": 9500000000, - "bob": 9500000000, - "carol": 9500000000 - }, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.CreateIbcClientsAction", - "Action": { - "ChainA": "sover", - "ChainB": "provi" - }, - "State": {} - }, - { - "ActionType": "main.AddIbcChannelAction", - "Action": { - "ChainA": "sover", - "ChainB": "provi", - "ConnectionA": 0, - "PortA": "transfer", - "PortB": "transfer", - "Order": "unordered", - "Version": "ics20-1" - }, - "State": {} - }, - { - "ActionType": "main.LegacyUpgradeProposalAction", - "Action": { - "ChainID": "sover", - "UpgradeTitle": "sovereign-changeover", - "Proposer": "alice", - "UpgradeHeight": 110 - }, - "State": { - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": { - "1": { - "RawProposal": { - "Title": "sovereign-changeover", - "Description": "", - "UpgradeHeight": 110, - "Type": "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", - "Deposit": 10000000, - "Status": "2" - }, - "Type": "e2e.UpgradeProposal" - } - } - } - } - }, - { - "ActionType": "main.VoteGovProposalAction", - "Action": { - "Chain": "sover", - "From": [ - "alice" - ], - "Vote": [ - "yes" - ], - "PropNumber": 1 - }, - "State": { - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": { - "1": { - "RawProposal": { - "Title": "sovereign-changeover", - "Description": "", - "UpgradeHeight": 110, - "Type": "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", - "Deposit": 10000000, - "Status": "3" - }, - "Type": "e2e.UpgradeProposal" - } - } - } - } - }, - { - "ActionType": "main.WaitUntilBlockAction", - "Action": { - "Block": 110, - "Chain": "sover" - }, - "State": {} - }, - { - "ActionType": "main.SubmitConsumerAdditionProposalAction", - "Action": { - "PreCCV": true, - "Chain": "provi", - "From": "alice", - "Deposit": 10000001, - "ConsumerChain": "sover", - "SpawnTime": 0, - "InitialHeight": { - "revision_height": 111 - }, - "DistributionChannel": "channel-0", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null - }, - "State": { - "provi": { - "ValBalances": { - "alice": 9489999999, - "bob": 9500000000 - }, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": { - "1": { - "RawProposal": { - "Deposit": 10000001, - "Chain": "sover", - "SpawnTime": 0, - "InitialHeight": { - "revision_height": 111 - }, - "Status": "2" - }, - "Type": "e2e.ConsumerAdditionProposal" - } - } - } - } - }, - { - "ActionType": "main.VoteGovProposalAction", - "Action": { - "Chain": "provi", - "From": [ - "alice", - "bob", - "carol" - ], - "Vote": [ - "yes", - "yes", - "yes" - ], - "PropNumber": 1 - }, - "State": { - "provi": { - "ValBalances": { - "alice": 9500000000, - "bob": 9500000000 - }, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": { - "1": { - "RawProposal": { - "Deposit": 10000001, - "Chain": "sover", - "SpawnTime": 0, - "InitialHeight": { - "revision_height": 111 - }, - "Status": "3" - }, - "Type": "e2e.ConsumerAdditionProposal" - } - } - } - } - }, - { - "ActionType": "main.ChangeoverChainAction", - "Action": { - "SovereignChain": "sover", - "ProviderChain": "provi", - "Validators": [ - { - "Id": "alice", - "Allocation": 10000000000, - "Stake": 500000000 - }, - { - "Id": "bob", - "Allocation": 10000000000, - "Stake": 500000000 - }, - { - "Id": "carol", - "Allocation": 10000000000, - "Stake": 500000000 - } - ], - "GenesisChanges": "" - }, - "State": { - "provi": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 500, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - }, - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 500, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.AddIbcConnectionAction", - "Action": { - "ChainA": "sover", - "ChainB": "provi", - "ClientA": 1, - "ClientB": 1 - }, - "State": {} - }, - { - "ActionType": "main.AddIbcChannelAction", - "Action": { - "ChainA": "sover", - "ChainB": "provi", - "ConnectionA": 1, - "PortA": "consumer", - "PortB": "provider", - "Order": "ordered", - "Version": "" - }, - "State": {} - }, - { - "ActionType": "main.SendTokensAction", - "Action": { - "Chain": "sover", - "From": "alice", - "To": "bob", - "Amount": 100 - }, - "State": { - "sover": { - "ValBalances": { - "bob": 0 - }, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.DelegateTokensAction", - "Action": { - "Chain": "provi", - "From": "alice", - "To": "alice", - "Amount": 11000000 - }, - "State": { - "provi": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 511, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - }, - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 500, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.RelayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "sover", - "Port": "provider", - "Channel": 1 - }, - "State": { - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 511, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.SendTokensAction", - "Action": { - "Chain": "sover", - "From": "alice", - "To": "bob", - "Amount": 100 - }, - "State": { - "sover": { - "ValBalances": { - "bob": 100 - }, - "ProposedConsumerChains": null, - "ValPowers": null, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.UnbondTokensAction", - "Action": { - "Chain": "provi", - "Sender": "alice", - "UnbondFrom": "alice", - "Amount": 1000000 - }, - "State": { - "provi": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 510, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - }, - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 511, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.RelayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "sover", - "Port": "provider", - "Channel": 1 - }, - "State": { - "sover": { - "ValBalances": null, - "ProposedConsumerChains": null, - "ValPowers": { - "alice": 510, - "bob": 500, - "carol": 500 - }, - "StakedTokens": null, - "IBCTransferParams": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerPendingPacketQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "ClientsFrozenHeights": null, - "HasToValidate": null, - "Proposals": null - } - } - } -] \ No newline at end of file diff --git a/tests/e2e/v5/actions.go b/tests/e2e/v5/actions.go index 8dd3a5f1ce..fa206eddaa 100644 --- a/tests/e2e/v5/actions.go +++ b/tests/e2e/v5/actions.go @@ -43,10 +43,8 @@ type ( StartChainAction = e2e.StartChainAction StartChainValidator = e2e.StartChainValidator StartConsumerChainAction = e2e.StartConsumerChainAction - StartSovereignChainAction = e2e.StartSovereignChainAction SubmitConsumerRemovalProposalAction = e2e.SubmitConsumerRemovalProposalAction DelegateTokensAction = e2e.DelegateTokensAction - ChangeoverChainAction = e2e.ChangeoverChainAction UnbondTokensAction = e2e.UnbondTokensAction ) @@ -779,131 +777,6 @@ func (tr *Chain) transformConsumerGenesis(consumerChain ChainID, genesis []byte) return result } -func (tr Chain) changeoverChain( - action ChangeoverChainAction, - verbose bool, -) { - // sleep until the consumer chain genesis is ready on consumer - time.Sleep(5 * time.Second) - cmd := tr.Target.ExecCommand( - tr.TestConfig.ChainConfigs[action.ProviderChain].BinaryName, - - "query", "provider", "consumer-genesis", - string(tr.TestConfig.ChainConfigs[action.SovereignChain].ChainId), - - `--node`, tr.Target.GetQueryNode(action.ProviderChain), - `-o`, `json`, - ) - - if verbose { - log.Println("changeoverChain cmd: ", cmd.String()) - } - - bz, err := cmd.CombinedOutput() - if err != nil { - log.Fatal(err, "\n", string(bz)) - } - - consumerGenesis := ".app_state.ccvconsumer = " + string(bz) - consumerGenesisChanges := tr.TestConfig.ChainConfigs[action.SovereignChain].GenesisChanges - if consumerGenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges - } - if action.GenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + action.GenesisChanges - } - - tr.startChangeover(ChangeoverChainAction{ - Validators: action.Validators, - GenesisChanges: consumerGenesis, - }, verbose) -} - -func (tr Chain) startChangeover( - action ChangeoverChainAction, - verbose bool, -) { - chainConfig := tr.TestConfig.ChainConfigs[ChainID("sover")] - type jsonValAttrs struct { - Mnemonic string `json:"mnemonic"` - Allocation string `json:"allocation"` - Stake string `json:"stake"` - ValId string `json:"val_id"` - PrivValidatorKey string `json:"priv_validator_key"` - NodeKey string `json:"node_key"` - IpSuffix string `json:"ip_suffix"` - - ConsumerMnemonic string `json:"consumer_mnemonic"` - ConsumerPrivValidatorKey string `json:"consumer_priv_validator_key"` - StartWithConsumerKey bool `json:"start_with_consumer_key"` - } - - var validators []jsonValAttrs - for _, val := range action.Validators { - validators = append(validators, jsonValAttrs{ - Mnemonic: tr.TestConfig.ValidatorConfigs[val.Id].Mnemonic, - NodeKey: tr.TestConfig.ValidatorConfigs[val.Id].NodeKey, - ValId: fmt.Sprint(val.Id), - PrivValidatorKey: tr.TestConfig.ValidatorConfigs[val.Id].PrivValidatorKey, - Allocation: fmt.Sprint(val.Allocation) + "stake", - Stake: fmt.Sprint(val.Stake) + "stake", - IpSuffix: tr.TestConfig.ValidatorConfigs[val.Id].IpSuffix, - - ConsumerMnemonic: tr.TestConfig.ValidatorConfigs[val.Id].ConsumerMnemonic, - ConsumerPrivValidatorKey: tr.TestConfig.ValidatorConfigs[val.Id].ConsumerPrivValidatorKey, - // if true node will be started with consumer key for each consumer chain - StartWithConsumerKey: tr.TestConfig.ValidatorConfigs[val.Id].UseConsumerKey, - }) - } - - vals, err := json.Marshal(validators) - if err != nil { - log.Fatal(err) - } - - // Concat genesis changes defined in chain config, with any custom genesis changes for this chain instantiation - var genesisChanges string - if action.GenesisChanges != "" { - genesisChanges = chainConfig.GenesisChanges + " | " + action.GenesisChanges - } else { - genesisChanges = chainConfig.GenesisChanges - } - - isConsumer := true - changeoverScript := tr.Target.GetTestScriptPath(isConsumer, "start-changeover.sh") - cmd := tr.Target.ExecCommand( - "/bin/bash", - changeoverScript, chainConfig.UpgradeBinary, string(vals), - "sover", chainConfig.IpPrefix, genesisChanges, - tr.TestConfig.TendermintConfigOverride, - ) - - cmdReader, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - cmd.Stderr = cmd.Stdout - - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - - scanner := bufio.NewScanner(cmdReader) - - for scanner.Scan() { - out := scanner.Text() - if verbose { - fmt.Println("startChangeover: " + out) - } - if out == done { - break - } - } - if err := scanner.Err(); err != nil { - log.Fatal("startChangeover died", err) - } -} - type AddChainToRelayerAction struct { Chain ChainID Validator ValidatorID From 479421e8e6e9dcc8cd2f12e4ed916b66421bcf59 Mon Sep 17 00:00:00 2001 From: mpoke Date: Tue, 7 Jan 2025 17:19:56 +0100 Subject: [PATCH 24/25] apply review suggestions --- docs/docs/consumer-development/changeover-procedure.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 9b4736dfdd..1f9f88d5ae 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -6,6 +6,8 @@ sidebar_position: 6 Chains that were **not** initially launched as consumers of Interchain Security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a consumer chain is called the **changeover procedure** and is part of the Interchain Security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. +In a nutshell, to become an ICS consumer chain, a standalone chain needs to add the `x/ccv/consumer` module (via a coordinated upgrade) and to transfer validation responsibilities to the provider validators as stated in `consumer_genesis.json`. + The relevant protocol specifications are available below: * [ICS-28 with existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains). * [ADR in ICS repo](../adrs/adr-010-standalone-changeover.md) @@ -73,6 +75,6 @@ Therefore, when creating a new consumer chain on the provider, the following cha Before the upgrade of the standalone chain (i.e., adding the `x/ccv/consumer` module), the consumer module genesis state created by the provider at `spawn_time` must be adapted to older versions of the consumer module. This consists of two changes. -First, by setting `connection_id` to an empty string, the provider will set the `preCCV` flag in the `ConsumerGenesisState` struct to `false`. This must be changed to `true` in order to trigger the changeover procedure logic on the `x/ccv/consumer` module. +First, by setting `connection_id` in the consumer initialization parameters to an empty string, the provider will set the `preCCV` flag in the `ConsumerGenesisState` struct to `false`. This must be changed to `true` in order to trigger the changeover procedure logic on the `x/ccv/consumer` module. Second, the `connection_id` field of `ConsumerGenesisState` must be removed to enable older versions of the consumer module to unmarshal the consumer module genesis state obtained from the provider. This can be done using the `interchain-security-cd genesis transform` CLI command. \ No newline at end of file From 36515a2defefa8494ab4fb7fa87432af9620c44d Mon Sep 17 00:00:00 2001 From: mpoke Date: Tue, 7 Jan 2025 17:33:09 +0100 Subject: [PATCH 25/25] do not remove preCCV from consumer genesis state --- app/consumer/genesis.go | 4 ++-- app/consumer/genesis_test.go | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index fb087d7f4e..8c5c153797 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -92,9 +92,9 @@ func transformGenesis(targetVersion IcsVersion, jsonRaw []byte) (json.RawMessage if err != nil { break } - genState, err = removeFieldsFromGenesisState(genState, []string{"preCCV", "connection_id"}) + genState, err = removeFieldsFromGenesisState(genState, []string{"connection_id"}) case v4_5_x, v6_x_x: - genState, err = removeFieldsFromGenesisState(genState, []string{"preCCV", "connection_id"}) + genState, err = removeFieldsFromGenesisState(genState, []string{"connection_id"}) default: err = fmt.Errorf("unsupported target version '%s'. Run %s --help", targetVersion, version.AppName) diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index 75693faa83..9e29d8570f 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -406,12 +406,9 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str _, consumerIdFound := params["consumer_id"] require.Equal(t, shouldContainConsumerId(targetVersion), consumerIdFound) - // Check for preCCV - _, found = resultRaw["preCCV"] - require.Equal(t, shouldContainPreCCVAndConnectionId(targetVersion), found) // Check for no connection_id _, found = resultRaw["connection_id"] - require.Equal(t, shouldContainPreCCVAndConnectionId(targetVersion), found) + require.Equal(t, shouldContainConnectionId(targetVersion), found) // Iterate over all fields of ConsumerParams and check: // - that they match between source and result genesis @@ -427,10 +424,7 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str if fieldName == "ConsumerId" && !shouldContainConsumerId(targetVersion) { // ConsumerId is not present in v5.x => expect empty string when unmarshalled to v6 require.EqualValues(t, "", resultField, "Field %s does not match", fieldName) - } else if fieldName == "PreCCV" && !shouldContainPreCCVAndConnectionId(targetVersion) { - // PreCCV is not present in expect false when unmarshalled it - require.EqualValues(t, false, resultField, "Field %s does not match", fieldName) - } else if fieldName == "ConnectionId" && !shouldContainPreCCVAndConnectionId(targetVersion) { + } else if fieldName == "ConnectionId" && !shouldContainConnectionId(targetVersion) { // ConnectionId is not present in expect empty string when unmarshalled it require.EqualValues(t, "", resultField, "Field %s does not match", fieldName) } else { @@ -448,7 +442,7 @@ func CheckGenesisTransform(t *testing.T, sourceVersion string, targetVersion str for i := 0; i < srcParams.NumField(); i++ { fieldName := srcType.Field(i).Name // Skip Params field as it was checked above - if fieldName == "Params" || fieldName == "PreCCV" || fieldName == "ConnectionId" { + if fieldName == "Params" || fieldName == "ConnectionId" { continue } srcField := srcParams.Field(i).Interface() @@ -469,7 +463,7 @@ func shouldContainConsumerId(version string) bool { return false } -func shouldContainPreCCVAndConnectionId(version string) bool { +func shouldContainConnectionId(version string) bool { switch version { case Consumer_v4_x_x, Consumer_v4_5_x, Consumer_v5_x_x, Consumer_v6_x_x: return false