Skip to content

Commit

Permalink
rebased to pick up the removal of legacy proposals (#2130) and re-int…
Browse files Browse the repository at this point in the history
…roduced old messages so that existing proposals can deserialize
  • Loading branch information
insumity committed Aug 15, 2024
1 parent 8a0b825 commit 96b5706
Show file tree
Hide file tree
Showing 7 changed files with 4,292 additions and 1,686 deletions.
141 changes: 141 additions & 0 deletions proto/interchain_security/ccv/provider/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,144 @@ message ConsumerInitializationRecord {

// MsgInitializeConsumerResponse defines response type for MsgRegisterConsumer
message MsgInitializeConsumerResponse {}


// Keeping the old messages (`MsgConsumerAddition`, `MsgConsumerRemoval`, `MsgConsumerModification`) here so that
// existing proposals can be deserialized

message MsgConsumerAddition {
option (cosmos.msg.v1.signer) = "authority";

// the proposed chain-id of the new consumer chain, must be different from all
// other consumer chain ids of the executing provider chain.
string chain_id = 1;
// the proposed initial height of new consumer chain.
// For a completely new chain, this will be {0,1}. However, it may be
// different if this is a chain that is converting to a consumer chain.
ibc.core.client.v1.Height initial_height = 2 [ (gogoproto.nullable) = false ];
// The hash of the consumer chain genesis state without the consumer CCV
// module genesis params. It is used for off-chain confirmation of
// genesis.json validity by validators and other parties.
bytes genesis_hash = 3;
// The hash of the consumer chain binary that should be run by validators on
// chain initialization. It is used for off-chain confirmation of binary
// validity by validators and other parties.
bytes binary_hash = 4;
// spawn time is the 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.
google.protobuf.Timestamp spawn_time = 5
[ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ];

// Unbonding period for the consumer,
// which should be smaller than that of the provider in general.
google.protobuf.Duration unbonding_period = 6
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ];
// Sent CCV related IBC packets will timeout after this duration
google.protobuf.Duration ccv_timeout_period = 7
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ];
// Sent transfer related IBC packets will timeout after this duration
google.protobuf.Duration transfer_timeout_period = 8
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ];
// 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%.
string consumer_redistribution_fraction = 9;
// BlocksPerDistributionTransmission is the number of blocks between
// ibc-token-transfers from the consumer chain to the provider chain. On
// sending transmission event, `consumer_redistribution_fraction` of the
// accumulated tokens are sent to the consumer redistribution address.
int64 blocks_per_distribution_transmission = 10;
// 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.
int64 historical_entries = 11;
// 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 sovereign to consumer
// changeover in order to maintain 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 = 18 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Corresponds to the minimal amount of (provider chain) stake required to validate on the consumer chain.
uint64 min_stake = 19;
// Corresponds to whether inactive validators are allowed to validate the consumer chain.
bool allow_inactive_vals = 20;
}

// MsgConsumerAdditionResponse defines response type for MsgConsumerAddition messages
message MsgConsumerAdditionResponse {}

message MsgConsumerRemoval {
option (cosmos.msg.v1.signer) = "authority";

// the chain-id of the consumer chain to be stopped
string chain_id = 1;
// the time on the provider chain at which all validators are responsible to
// stop their consumer chain validator node
google.protobuf.Timestamp stop_time = 2
[ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ];
// signer address
string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgConsumerRemovalResponse defines response type for MsgConsumerRemoval messages
message MsgConsumerRemovalResponse {}

// 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.
//
// Note: this replaces ConsumerModificationProposal which is deprecated and will be removed soon
message MsgConsumerModification {
// the title of the proposal
string title = 1;
// the description of the proposal
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 = 9 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

message MsgConsumerModificationResponse {}
6 changes: 3 additions & 3 deletions tests/integration/provider_gov_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ func (s *CCVTestSuite) TestAfterPropSubmissionAndVotingPeriodEnded() {
providerKeeper.Hooks().AfterProposalSubmission(ctx, proposal.Id)

// verify that the proposal ID is created
proposalIdOnProvider, ok := providerKeeper.GetProposedConsumerChain(ctx, proposal.Id)
consumerIdOnProvider, ok := providerKeeper.GetProposedConsumerChain(ctx, proposal.Id)
s.Require().True(ok)
s.Require().NotEmpty(proposalIdOnProvider)
s.Require().Equal(addConsumerProp.ChainId, proposalIdOnProvider)
s.Require().NotEmpty(consumerIdOnProvider)
s.Require().Equal("0", consumerIdOnProvider)

providerKeeper.Hooks().AfterProposalVotingPeriodEnded(ctx, proposal.Id)
// verify that the proposal ID is deleted
Expand Down
6 changes: 3 additions & 3 deletions x/ccv/provider/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package keeper

import (
"context"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkgov "github.com/cosmos/cosmos-sdk/x/gov/types"
Expand Down Expand Up @@ -110,8 +109,9 @@ func (h Hooks) BeforeTokenizeShareRecordRemoved(_ context.Context, _ uint64) err
// that maps the proposal ID to the consumer chain ID.
func (h Hooks) AfterProposalSubmission(goCtx context.Context, proposalID uint64) error {
ctx := sdk.UnwrapSDKContext(goCtx)
if p, ok := h.GetConsumerAdditionFromProp(ctx, proposalID); ok {
h.k.SetProposedConsumerChain(ctx, p.ChainId, proposalID)
if _, ok := h.GetConsumerAdditionFromProp(ctx, proposalID); ok {
consumerId := h.k.FetchAndIncrementConsumerId(ctx)
h.k.SetProposedConsumerChain(ctx, consumerId, proposalID)
}
return nil
}
Expand Down
4 changes: 4 additions & 0 deletions x/ccv/provider/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
&MsgInitializeConsumer{},
&MsgUpdateConsumer{},
&MsgRemoveConsumer{},
// keeping old messages (for now) so that existing proposals can be correctly deserialized
&MsgConsumerAddition{},
&MsgConsumerRemoval{},
&MsgConsumerModification{},
&MsgChangeRewardDenoms{},
&MsgUpdateParams{},
)
Expand Down
68 changes: 35 additions & 33 deletions x/ccv/provider/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,39 @@ import (

// Provider sentinel errors
var (
ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal")
ErrInvalidConsumerRemoval = errorsmod.Register(ModuleName, 2, "invalid consumer removal")
ErrUnknownConsumerId = errorsmod.Register(ModuleName, 3, "no consumer chain with this consumer id")
ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id")
ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key")
ErrInvalidConsumerId = errorsmod.Register(ModuleName, 6, "invalid consumer id")
ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found")
ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address")
ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address")
ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator")
ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment")
ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params")
ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address")
ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom")
ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address")
ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client")
ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists")
ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found")
ErrInvalidConsumerCommissionRate = errorsmod.Register(ModuleName, 19, "consumer commission rate is invalid")
ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain")
ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id")
ErrInvalidUpdateRecord = errorsmod.Register(ModuleName, 22, "invalid consumer update record")
ErrNoUnbondingTime = errorsmod.Register(ModuleName, 23, "provider unbonding time not found")
ErrInvalidAddress = errorsmod.Register(ModuleName, 24, "invalid address")
ErrUnauthorized = errorsmod.Register(ModuleName, 25, "unauthorized")
ErrInvalidPhase = errorsmod.Register(ModuleName, 26, "cannot perform action in the current phase of consumer chain")
ErrNoInitializationRecord = errorsmod.Register(ModuleName, 27, "initialization record is missing")
ErrNoRegistrationRecord = errorsmod.Register(ModuleName, 28, "registration record is missing")
ErrNoChainId = errorsmod.Register(ModuleName, 29, "missing chain id for consumer chain")
ErrNoConsumerGenesis = errorsmod.Register(ModuleName, 30, "missing consumer genesis")
ErrInvalidConsumerGenesis = errorsmod.Register(ModuleName, 31, "invalid consumer genesis")
ErrNoConsumerId = errorsmod.Register(ModuleName, 32, "missing consumer id")
ErrAlreadyOptedIn = errorsmod.Register(ModuleName, 33, "already opted in to a chain with the same chain id")
ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal")
ErrInvalidConsumerRemoval = errorsmod.Register(ModuleName, 2, "invalid consumer removal")
ErrUnknownConsumerId = errorsmod.Register(ModuleName, 3, "no consumer chain with this consumer id")
ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id")
ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key")
ErrInvalidConsumerId = errorsmod.Register(ModuleName, 6, "invalid consumer id")
ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found")
ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address")
ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address")
ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator")
ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment")
ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params")
ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address")
ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom")
ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address")
ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client")
ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists")
ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found")
ErrInvalidConsumerCommissionRate = errorsmod.Register(ModuleName, 19, "consumer commission rate is invalid")
ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain")
ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id")
ErrInvalidConsumerModificationProposal = errorsmod.Register(ModuleName, 22, "invalid consumer modification proposal")
ErrInvalidUpdateRecord = errorsmod.Register(ModuleName, 23, "invalid consumer update record")
ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 24, "consumer chain id must not be blank")
ErrNoUnbondingTime = errorsmod.Register(ModuleName, 25, "provider unbonding time not found")
ErrInvalidAddress = errorsmod.Register(ModuleName, 26, "invalid address")
ErrUnauthorized = errorsmod.Register(ModuleName, 27, "unauthorized")
ErrInvalidPhase = errorsmod.Register(ModuleName, 28, "cannot perform action in the current phase of consumer chain")
ErrNoInitializationRecord = errorsmod.Register(ModuleName, 29, "initialization record is missing")
ErrNoRegistrationRecord = errorsmod.Register(ModuleName, 30, "registration record is missing")
ErrNoChainId = errorsmod.Register(ModuleName, 31, "missing chain id for consumer chain")
ErrNoConsumerGenesis = errorsmod.Register(ModuleName, 32, "missing consumer genesis")
ErrInvalidConsumerGenesis = errorsmod.Register(ModuleName, 33, "invalid consumer genesis")
ErrNoConsumerId = errorsmod.Register(ModuleName, 34, "missing consumer id")
ErrAlreadyOptedIn = errorsmod.Register(ModuleName, 35, "already opted in to a chain with the same chain id")
)
Loading

0 comments on commit 96b5706

Please sign in to comment.