Skip to content
83 changes: 0 additions & 83 deletions proto/interchain_security/ccv/consumer/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -81,86 +81,3 @@ message ConsumerPacketDataList {
repeated interchain_security.ccv.v1.ConsumerPacketData list = 1
[ (gogoproto.nullable) = false ];
}
syntax = "proto3";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow this invalid duplicate got here (I haven't looked on git blame yet) but proto was erroring out and I deleted to fix.


package interchain_security.ccv.consumer.v1;

option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types";

import "interchain_security/ccv/v1/shared_consumer.proto";
import "ibc/lightclients/tendermint/v1/tendermint.proto";

import "gogoproto/gogo.proto";
import "interchain_security/ccv/v1/wire.proto";
import "google/protobuf/timestamp.proto";
import "tendermint/abci/types.proto";

// GenesisState defines the CCV consumer genesis state
//
// Note: this type is only used on consumer side and references shared types
// with provider
message GenesisState {
// Reserve 5th slot for removed provider_client_state field
reserved 5;

// Reserve 6th slot for removed provider_consensus_state field
reserved 6;

// Reserve 7th slot for removed maturing_packets field
reserved 7;

// Reserve 8th slot for removed initial_val_set field
reserved 8;

// ConsumerParams is a shared type with provider module
interchain_security.ccv.v1.ConsumerParams params = 1
[ (gogoproto.nullable) = false ];
// Client ID of the provider. Empty for a new chain, filled in on restart.
string provider_client_id = 2;
// Channel ID of the provider. Empty for a new chain, filled in on restart.
string provider_channel_id = 3;
// true for new chain, false for chain restart.
bool new_chain = 4;
// HeightToValsetUpdateId nil on new chain, filled in on restart.
repeated HeightToValsetUpdateID height_to_valset_update_id = 9
[ (gogoproto.nullable) = false ];
// OutstandingDowntimes nil on new chain, filled in on restart.
repeated OutstandingDowntime outstanding_downtime_slashing = 10
[ (gogoproto.nullable) = false ];
// PendingConsumerPackets nil on new chain, filled in on restart.
ConsumerPacketDataList pending_consumer_packets = 11
[ (gogoproto.nullable) = false ];
// 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 ];
}

// HeightValsetUpdateID represents a mapping internal to the consumer CCV module
// which links a block height to each recv valset update id.
message HeightToValsetUpdateID {
uint64 height = 1;
uint64 valset_update_id = 2;
}

// OutstandingDowntime defines the type used internally to the consumer CCV
// module and is used in order to not send multiple slashing requests for
// the same downtime infraction.
message OutstandingDowntime { string validator_consensus_address = 1; }

// LastTransmissionBlockHeight is the last time validator holding
// pools were transmitted to the provider chain. This type is used internally
// to the consumer CCV module.
message LastTransmissionBlockHeight { int64 height = 1; }

// ConsumerPacketDataList is a list of consumer packet data packets.
//
// Note this type is used internally to the consumer CCV module
// for exporting / importing state in InitGenesis and ExportGenesis.
message ConsumerPacketDataList {
repeated interchain_security.ccv.v1.ConsumerPacketData list = 1
[ (gogoproto.nullable) = false ];
}
52 changes: 52 additions & 0 deletions proto/interchain_security/ccv/provider/v1/provider.proto
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,32 @@ message ConsumerAdditionProposal {
// chain. it is most relevant for chains performing a sovereign 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. For example, 53 corresponds to a Top 53% chain,
// meaning that the top 53% provider validators by voting power have to
// validate the proposed consumer chain. top_N can either be 0 or any value in
// [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with
// top_N ∈ [50, 100] as a Top N chain.
uint32 top_N = 15;
// Corresponds to the maximum power (percentage-wise) a validator can have on
// the consumer chain. For instance, if `validators_power_cap` is set to 32,
// it means that no validator can have more than 32% of the voting power on
// the consumer chain. Note that this might not be feasible. For example,
// think of a consumer chain with only 5 validators and with
// `validators_power_cap` set to 10%. In such a scenario, at least one
// validator would need to have more than 20% of the total voting power.
// Therefore, `validators_power_cap` operates on a best-effort basis.
uint32 validators_power_cap = 16;
// Corresponds to the maximum number of validators that can validate a
// consumer chain. Only applicable to Opt In chains. Setting
// `validator_set_cap` on a Top N chain is a no-op.
uint32 validator_set_cap = 17;
// Corresponds to a list of provider consensus addresses of validators that
// are the ONLY ones that can validate the consumer chain.
repeated string allowlist = 18;
// Corresponds to a list of provider consensus addresses of validators that
// CANNOT validate the consumer chain.
repeated string denylist = 19;
}

// ConsumerRemovalProposal is a governance proposal on the provider chain to
Expand Down Expand Up @@ -120,6 +146,32 @@ message ConsumerModificationProposal {
string description = 2;
// the chain-id of the consumer chain to be modified
string chain_id = 3;
// Corresponds to the percentage of validators that have to validate the chain
// under the Top N case. For example, 53 corresponds to a Top 53% chain,
// meaning that the top 53% provider validators by voting power have to
// validate the proposed consumer chain. top_N can either be 0 or any value in
// [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with
// top_N ∈ [50, 100] as a Top N chain.
uint32 top_N = 4;
// Corresponds to the maximum power (percentage-wise) a validator can have on
// the consumer chain. For instance, if `validators_power_cap` is set to 32,
// it means that no validator can have more than 32% of the voting power on
// the consumer chain. Note that this might not be feasible. For example,
// think of a consumer chain with only 5 validators and with
// `validators_power_cap` set to 10%. In such a scenario, at least one
// validator would need to have more than 20% of the total voting power.
// Therefore, `validators_power_cap` operates on a best-effort basis.
uint32 validators_power_cap = 5;
// Corresponds to the maximum number of validators that can validate a
// consumer chain. Only applicable to Opt In chains. Setting
// `validator_set_cap` on a Top N chain is a no-op.
uint32 validator_set_cap = 6;
// Corresponds to a list of provider consensus addresses of validators that
// are the ONLY ones that can validate the consumer chain.
repeated string allowlist = 7;
// Corresponds to a list of provider consensus addresses of validators that
// CANNOT validate the consumer chain.
repeated string denylist = 8;
}

// EquivocationProposal is a governance proposal on the provider chain to
Expand Down
24 changes: 24 additions & 0 deletions proto/interchain_security/ccv/provider/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ service Query {
option (google.api.http).get =
"/interchain_security/ccv/provider/consumer_validators/{chain_id}";
}

// QueryConsumerChainOptedInValidators returns all opted-in validators for a
// given consumer chain
rpc QueryConsumerChainOptedInValidators(
QueryConsumerChainOptedInValidatorsRequest)
returns (QueryConsumerChainOptedInValidatorsResponse) {
option (google.api.http).get =
"/interchain_security/ccv/provider/opted_in_validators/{chain_id}";
}
}

message QueryConsumerGenesisRequest { string chain_id = 1; }
Expand Down Expand Up @@ -135,6 +144,12 @@ message QueryConsumerChainStopProposalsResponse {
message Chain {
string chain_id = 1;
string client_id = 2;
// If chain with `chainID` is a Top-N chain, i.e., enforces at least one
// validator to validate chain `chainID`
uint32 top_N = 3;
// If the chain is a Top-N chain, this is the minimum power required to be in
// the top N. Otherwise, this is -1.
int64 min_power_in_top_N = 4;
}

message QueryValidatorConsumerAddrRequest {
Expand Down Expand Up @@ -235,3 +250,12 @@ message QueryConsumerValidatorsValidator {
message QueryConsumerValidatorsResponse {
repeated QueryConsumerValidatorsValidator validators = 1;
}

message QueryConsumerChainOptedInValidatorsRequest {
string chain_id = 1;
}

message QueryConsumerChainOptedInValidatorsResponse {
// The consensus addresses of opted-in validators on the provider chain
repeated string validators_provider_addresses = 1;
}
94 changes: 92 additions & 2 deletions proto/interchain_security/ccv/provider/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ service Msg {
returns (MsgConsumerAdditionResponse);
rpc ConsumerRemoval(MsgConsumerRemoval) returns (MsgConsumerRemovalResponse);
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
rpc OptIn(MsgOptIn) returns (MsgOptInResponse);
rpc OptOut(MsgOptOut) returns (MsgOptOutResponse);
rpc ConsumerModification(MsgConsumerModification)
returns (MsgConsumerModificationResponse);
}
Expand Down Expand Up @@ -161,8 +163,34 @@ message MsgConsumerAddition {
// chain. it is most relevant for chains performing a sovereign to consumer
// changeover in order to maintan the existing ibc transfer channel
string distribution_transmission_channel = 12;
// Corresponds to the percentage of validators that have to validate the chain
// under the Top N case. For example, 53 corresponds to a Top 53% chain,
// meaning that the top 53% provider validators by voting power have to
// validate the proposed consumer chain. top_N can either be 0 or any value in
// [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with
// top_N ∈ [50, 100] as a Top N chain.
uint32 top_N = 13;
// Corresponds to the maximum power (percentage-wise) a validator can have on
// the consumer chain. For instance, if `validators_power_cap` is set to 32,
// it means that no validator can have more than 32% of the voting power on
// the consumer chain. Note that this might not be feasible. For example,
// think of a consumer chain with only 5 validators and with
// `validators_power_cap` set to 10%. In such a scenario, at least one
// validator would need to have more than 20% of the total voting power.
// Therefore, `validators_power_cap` operates on a best-effort basis.
uint32 validators_power_cap = 14;
// Corresponds to the maximum number of validators that can validate a
// consumer chain. Only applicable to Opt In chains. Setting
// `validator_set_cap` on a Top N chain is a no-op.
uint32 validator_set_cap = 15;
// Corresponds to a list of provider consensus addresses of validators that
// are the ONLY ones that can validate the consumer chain.
repeated string allowlist = 16;
// Corresponds to a list of provider consensus addresses of validators that
// CANNOT validate the consumer chain.
repeated string denylist = 17;
// signer address
string authority = 13 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
string authority = 18 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

// MsgConsumerAdditionResponse defines response type for MsgConsumerAddition
Expand Down Expand Up @@ -213,6 +241,42 @@ message MsgChangeRewardDenoms {
// messages
message MsgChangeRewardDenomsResponse {}

message MsgOptIn {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (cosmos.msg.v1.signer) = "signer";
// the chain id of the consumer chain to opt in to
string chain_id = 1;
// the validator address on the provider
string provider_addr = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ];
// (optional) The consensus public key to use on the consumer in json string
// format corresponding to proto-any, for example
// `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`.
// This field is optional and can remain empty (i.e., `consumer_key = ""`). A
// validator can always change the consumer public key at a later stage by
// issuing a `MsgAssignConsumerKey` message.
string consumer_key = 3;
// signer address
string signer = 4 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

message MsgOptInResponse {}

message MsgOptOut {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (cosmos.msg.v1.signer) = "signer";
// the chain id of the consumer chain to opt out from
string chain_id = 1;
// the validator address on the provider
string provider_addr = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ];
// signer address
string signer = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];

}

message MsgOptOutResponse {}

// MsgConsumerModification message contains a governance proposal on the
// provider chain to modify a running consumer chain. If it passes, the consumer
// chain's parameters are updated.
Expand All @@ -228,8 +292,34 @@ message MsgConsumerModification {
string description = 2;
// the chain-id of the consumer chain to be modified
string chain_id = 3;
// Corresponds to the percentage of validators that have to validate the chain
// under the Top N case. For example, 53 corresponds to a Top 53% chain,
// meaning that the top 53% provider validators by voting power have to
// validate the proposed consumer chain. top_N can either be 0 or any value in
// [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with
// top_N ∈ [50, 100] as a Top N chain.
uint32 top_N = 4;
// Corresponds to the maximum power (percentage-wise) a validator can have on
// the consumer chain. For instance, if `validators_power_cap` is set to 32,
// it means that no validator can have more than 32% of the voting power on
// the consumer chain. Note that this might not be feasible. For example,
// think of a consumer chain with only 5 validators and with
// `validators_power_cap` set to 10%. In such a scenario, at least one
// validator would need to have more than 20% of the total voting power.
// Therefore, `validators_power_cap` operates on a best-effort basis.
uint32 validators_power_cap = 5;
// Corresponds to the maximum number of validators that can validate a
// consumer chain. Only applicable to Opt In chains. Setting
// `validator_set_cap` on a Top N chain is a no-op.
uint32 validator_set_cap = 6;
// Corresponds to a list of provider consensus addresses of validators that
// are the ONLY ones that can validate the consumer chain.
repeated string allowlist = 7;
// Corresponds to a list of provider consensus addresses of validators that
// CANNOT validate the consumer chain.
repeated string denylist = 8;
// signer address
string authority = 4 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
string authority = 9 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

message MsgConsumerModificationResponse {}
3 changes: 3 additions & 0 deletions proto/interchain_security/ccv/v1/shared_consumer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ message ConsumerParams {
google.protobuf.Duration unbonding_period = 9
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ];

// Reserved for previously used soft_opt_out_threshold field
reserved 10;

// Reward denoms. These are the denominations which are allowed to be sent to
// the provider as rewards.
repeated string reward_denoms = 11;
Expand Down
2 changes: 2 additions & 0 deletions tests/e2e/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ type SubmitConsumerAdditionProposalAction struct {
SpawnTime uint
InitialHeight clienttypes.Height
DistributionChannel string
TopN uint32
}

func (tr Chain) submitConsumerAdditionProposal(
Expand All @@ -284,6 +285,7 @@ func (tr Chain) submitConsumerAdditionProposal(
UnbondingPeriod: params.UnbondingPeriod,
Deposit: fmt.Sprint(action.Deposit) + `stake`,
DistributionTransmissionChannel: action.DistributionChannel,
TopN: action.TopN,
}

bz, err := json.Marshal(prop)
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/steps_start_chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint
ConsumerChain: ChainID(consumerName),
SpawnTime: 0,
InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1},
TopN: 100, // All validators must validate (100% = Replicated Security)
},
State: State{
ChainID("provi"): ChainState{
Expand Down
6 changes: 2 additions & 4 deletions testutil/ibc_testing/generic_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp](

prop := testkeeper.GetTestConsumerAdditionProp()
prop.ChainId = chainID
// For Replicated Security, all validators participate (no TopN parameter)
// For Replicated Security with TopN restoration, set TopN to 100 (all validators participate)
prop.Top_N = 100

// NOTE: we cannot use the time.Now() because the coordinator chooses a hardcoded start time
// using time.Now() could set the spawn time to be too far in the past or too far in the future
Expand All @@ -150,9 +151,6 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp](
providerKeeper.SetPendingConsumerAdditionProp(providerChain.GetContext(), prop)
props := providerKeeper.GetAllPendingConsumerAdditionProps(providerChain.GetContext())
s.Require().Len(props, 1, "unexpected len consumer addition proposals in AddConsumer")

// For Replicated Security, all validators automatically participate
// No opt-in needed

// commit the state on the provider chain
// and create the client and genesis of consumer
Expand Down
1 change: 1 addition & 0 deletions testutil/keeper/unit_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal {
types.DefaultCCVTimeoutPeriod,
types.DefaultTransferTimeoutPeriod,
types.DefaultConsumerUnbondingPeriod,
0, // TopN = 0 for opt-in chain (doesn't require validators for testing)
).(*providertypes.ConsumerAdditionProposal)

return prop
Expand Down
Loading
Loading