Skip to content

Commit

Permalink
feat: Equivocation gov proposal (#703)
Browse files Browse the repository at this point in the history
This change adds a new kind of gov proposal that will slash and
tombstone validators for double-signing.

The proposal handler is added in the `provider` module, and use the
`evidence` module to handle the equivocations.

Co-authored-by: Albert Le Batteux <[email protected]>
Co-authored-by: Jehan <[email protected]>
  • Loading branch information
3 people authored Feb 6, 2023
1 parent cbe4331 commit 50957d0
Show file tree
Hide file tree
Showing 17 changed files with 835 additions and 185 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ SDK_QUERY = third_party/proto/cosmos/base/query/v1beta1
SDK_BASE = third_party/proto/cosmos/base/v1beta1
SDK_UPGRADE = third_party/proto/cosmos/upgrade/v1beta1
SDK_STAKING = third_party/proto/cosmos/staking/v1beta1
SDK_EVIDENCE = third_party/proto/cosmos/evidence/v1beta1

GOGO_PROTO_TYPES = third_party/proto/gogoproto
CONFIO_TYPES = third_party/proto/confio
Expand All @@ -117,6 +118,9 @@ proto-update-deps:
@mkdir -p $(SDK_STAKING)
@curl -sSL $(SDK_PROTO_URL)/staking/v1beta1/staking.proto > $(SDK_STAKING)/staking.proto

@mkdir -p $(SDK_EVIDENCE)
@curl -sSL $(SDK_PROTO_URL)/evidence/v1beta1/evidence.proto > $(SDK_EVIDENCE)/evidence.proto

## Importing of tendermint protobuf definitions currently requires the
## use of `sed` in order to build properly with cosmos-sdk's proto file layout
## (which is the standard Buf.build FILE_LAYOUT)
Expand Down
22 changes: 11 additions & 11 deletions app/provider/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ var (
ibcclientclient.UpgradeProposalHandler,
ibcproviderclient.ConsumerAdditionProposalHandler,
ibcproviderclient.ConsumerRemovalProposalHandler,
ibcproviderclient.EquivocationProposalHandler,
),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
Expand Down Expand Up @@ -421,6 +422,14 @@ func New(
scopedIBCKeeper,
)

// create evidence keeper with router
app.EvidenceKeeper = *evidencekeeper.NewKeeper(
appCodec,
keys[evidencetypes.StoreKey],
app.StakingKeeper,
app.SlashingKeeper,
)

app.ProviderKeeper = ibcproviderkeeper.NewKeeper(
appCodec,
keys[providertypes.StoreKey],
Expand All @@ -433,6 +442,7 @@ func New(
app.StakingKeeper,
app.SlashingKeeper,
app.AccountKeeper,
app.EvidenceKeeper,
authtypes.FeeCollectorName,
)

Expand All @@ -446,7 +456,7 @@ func New(
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)).
AddRoute(providertypes.RouterKey, ibcprovider.NewConsumerChainProposalHandler(app.ProviderKeeper)).
AddRoute(providertypes.RouterKey, ibcprovider.NewProviderProposalHandler(app.ProviderKeeper)).
AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))

app.GovKeeper = govkeeper.NewKeeper(
Expand Down Expand Up @@ -479,16 +489,6 @@ func New(
ibcRouter.AddRoute(providertypes.ModuleName, providerModule)
app.IBCKeeper.SetRouter(ibcRouter)

// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
appCodec,
keys[evidencetypes.StoreKey],
app.StakingKeeper,
app.SlashingKeeper,
)

app.EvidenceKeeper = *evidenceKeeper

skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))

// NOTE: Any module instantiated in the module manager that is later modified
Expand Down
10 changes: 10 additions & 0 deletions proto/interchain_security/ccv/provider/v1/provider.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "google/protobuf/duration.proto";
import "ibc/core/client/v1/client.proto";
import "ibc/lightclients/tendermint/v1/tendermint.proto";
import "tendermint/crypto/keys.proto";
import "cosmos/evidence/v1beta1/evidence.proto";

// ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain.
// If it passes, then all validators on the provider chain are expected to validate the consumer chain at spawn time
Expand Down Expand Up @@ -77,6 +78,15 @@ message ConsumerRemovalProposal {
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}

message EquivocationProposal {
// the title of the proposal
string title = 1;
// the description of the proposal
string description = 2;
// the list of equivocations that will be processed
repeated cosmos.evidence.v1beta1.Equivocation equivocations = 3;
}

// A persisted queue entry indicating that a slash packet data instance needs to be handled.
// This type belongs in the "global" queue, to coordinate slash packet handling times between consumers.
message GlobalSlashEntry {
Expand Down
118 changes: 77 additions & 41 deletions testutil/keeper/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions testutil/keeper/unit_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type MockedKeepers struct {
*MockBankKeeper
*MockIBCTransferKeeper
*MockIBCCoreKeeper
*MockEvidenceKeeper
}

// NewMockedKeepers instantiates a struct with pointers to properly instantiated mocked keepers.
Expand All @@ -102,12 +103,12 @@ func NewMockedKeepers(ctrl *gomock.Controller) MockedKeepers {
MockBankKeeper: NewMockBankKeeper(ctrl),
MockIBCTransferKeeper: NewMockIBCTransferKeeper(ctrl),
MockIBCCoreKeeper: NewMockIBCCoreKeeper(ctrl),
MockEvidenceKeeper: NewMockEvidenceKeeper(ctrl),
}
}

// NewInMemProviderKeeper instantiates an in-mem provider keeper from params and mocked keepers
func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) providerkeeper.Keeper {

return providerkeeper.NewKeeper(
params.Cdc,
params.StoreKey,
Expand All @@ -120,13 +121,13 @@ func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) provi
mocks.MockStakingKeeper,
mocks.MockSlashingKeeper,
mocks.MockAccountKeeper,
mocks.MockEvidenceKeeper,
"",
)
}

// NewInMemConsumerKeeper instantiates an in-mem consumer keeper from params and mocked keepers
func NewInMemConsumerKeeper(params InMemKeeperParams, mocks MockedKeepers) consumerkeeper.Keeper {

return consumerkeeper.NewKeeper(
params.Cdc,
params.StoreKey,
Expand All @@ -150,8 +151,8 @@ func NewInMemConsumerKeeper(params InMemKeeperParams, mocks MockedKeepers) consu
// Note: Calling ctrl.Finish() at the end of a test function ensures that
// no unexpected calls to external keepers are made.
func GetProviderKeeperAndCtx(t *testing.T, params InMemKeeperParams) (
providerkeeper.Keeper, sdk.Context, *gomock.Controller, MockedKeepers) {

providerkeeper.Keeper, sdk.Context, *gomock.Controller, MockedKeepers,
) {
ctrl := gomock.NewController(t)
mocks := NewMockedKeepers(ctrl)
return NewInMemProviderKeeper(params, mocks), params.Ctx, ctrl, mocks
Expand All @@ -162,8 +163,8 @@ func GetProviderKeeperAndCtx(t *testing.T, params InMemKeeperParams) (
// Note: Calling ctrl.Finish() at the end of a test function ensures that
// no unexpected calls to external keepers are made.
func GetConsumerKeeperAndCtx(t *testing.T, params InMemKeeperParams) (
consumerkeeper.Keeper, sdk.Context, *gomock.Controller, MockedKeepers) {

consumerkeeper.Keeper, sdk.Context, *gomock.Controller, MockedKeepers,
) {
ctrl := gomock.NewController(t)
mocks := NewMockedKeepers(ctrl)
return NewInMemConsumerKeeper(params, mocks), params.Ctx, ctrl, mocks
Expand Down Expand Up @@ -219,8 +220,8 @@ func GetNewVSCMaturedPacketData() ccvtypes.VSCMaturedPacketData {
// SetupForStoppingConsumerChain registers expected mock calls and corresponding state setup
// which asserts that a consumer chain was properly stopped from StopConsumerChain().
func SetupForStoppingConsumerChain(t *testing.T, ctx sdk.Context,
providerKeeper *providerkeeper.Keeper, mocks MockedKeepers) {

providerKeeper *providerkeeper.Keeper, mocks MockedKeepers,
) {
expectations := GetMocksForCreateConsumerClient(ctx, &mocks,
"chainID", clienttypes.NewHeight(4, 5))
expectations = append(expectations, GetMocksForSetConsumerChain(ctx, &mocks, "chainID")...)
Expand Down
Loading

0 comments on commit 50957d0

Please sign in to comment.