Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADR 009: Evidence Module #4826

Merged
merged 33 commits into from
Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9170058
Add evidence module skeleton
alexanderbez Jul 31, 2019
4e10550
Add changelog and context
alexanderbez Jul 31, 2019
555fad0
Change ADR # and update decision section
alexanderbez Aug 1, 2019
8b05233
Add consequences
alexanderbez Aug 1, 2019
c987342
Updates
alexanderbez Aug 1, 2019
64cfb95
Updates
alexanderbez Aug 1, 2019
e9882b8
More updates
alexanderbez Aug 1, 2019
57364a8
Renaming
alexanderbez Aug 1, 2019
b8dfa24
Formatting
alexanderbez Aug 1, 2019
4fee610
Formatting
alexanderbez Aug 1, 2019
bdd8d36
Add TODO section
alexanderbez Aug 1, 2019
23343b1
Add section on mapping
alexanderbez Aug 1, 2019
6500482
Add section on genesis state
alexanderbez Aug 1, 2019
0daeff3
Add section headers
alexanderbez Aug 1, 2019
c641b9e
Add support for jailing
alexanderbez Aug 1, 2019
317d64e
Change ADR to 009
alexanderbez Aug 2, 2019
992dc02
Update context
alexanderbez Aug 9, 2019
9a31020
Update decision points
alexanderbez Aug 9, 2019
beb760c
Update decision points
alexanderbez Aug 9, 2019
b27f0a4
Markdown cleanup
alexanderbez Aug 9, 2019
57969ca
Add further details on the Infraction type
alexanderbez Aug 9, 2019
d929292
Add section on params
alexanderbez Aug 9, 2019
e991117
Update docs on jailable penalties
alexanderbez Aug 9, 2019
bb1fd3e
Merge branch 'master' into bez/adr-evidence-module
alexanderbez Oct 14, 2019
8d3d1de
adr: update context
alexanderbez Oct 15, 2019
5ff4570
adr: fix typos
alexanderbez Oct 15, 2019
e1d963d
Merge branch 'master' into bez/adr-evidence-module
alexanderbez Oct 15, 2019
57d23bd
adr: update decision section features
alexanderbez Oct 16, 2019
c273bb9
adr: simplify evidence slashing logic
alexanderbez Oct 16, 2019
a258585
adr: cleanup evidence interface and add member comments
alexanderbez Oct 16, 2019
074c3e1
adr: update router interface
alexanderbez Oct 16, 2019
56a7a33
Merge branch 'master' into bez/adr-evidence-module
alexanderbez Oct 16, 2019
7df9555
Merge branch 'master' into bez/adr-evidence-module
alexanderbez Oct 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/architecture/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Please add a entry below in your Pull Request for an ADR.

- [ADR 002: SDK Documentation Structure](./adr-002-docs-structure.md)
- [ADR 006: Secret Store Replacement](./adr-006-secret-store-replacement.md)
- [ADR 009: Evidence Module](./adr-009-evidence-module.md)
- [ADR 010: Modular AnteHandler](./adr-010-modular-antehandler.md)
- [ADR 011: Generalize Genesis Accounts](./adr-011-generalize-genesis-accounts.md)
- [ADR 012: State Accessors](./adr-012-state-accessors.md)
222 changes: 222 additions & 0 deletions docs/architecture/adr-009-evidence-module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# ADR 009: Evidence Module

## Changelog

- 2019 July 31: Initial draft

## Status

Proposed

## Context

In order to support building highly secure, robust and interoperable blockchain
applications, it is vital for the Cosmos SDK to expose a mechanism in which arbitrary
evidence can be submitted, evaluated and verified resulting in some agreed upon
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
penalty for any misbehavior committed by a validator, such as equivocation (double-voting),
signing when unbonded, signing an incorrect state transition (in the future), etc.
Furthermore, such a mechanism is paramount for any
[IBC](https://github.com/cosmos/ics/blob/master/ibc/1_IBC_ARCHITECTURE.md) or
cross-chain validation protocol implementation in order to support the ability
for any misbehavior to be relayed back from a collateralized chain to a primary
chain so that the equivocating validator(s) can be slashed.

## Decision

We will implement an evidence module in the Cosmos SDK supporting the following
functionality:

- Provide developers with the abstractions and interfaces necessary to define
custom evidence messages, message handlers, and methods to slash and penalize
accordingly for misbehavior.
- Support the ability to route evidence messages to handlers in any module to
determine the validity of submitted misbehavior.
- Support the ability, through governance, to modify slashing penalties of any
evidence type.
- Querier implementation to support querying params, evidence types, params, and
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
all submitted valid misbehavior.

### Types

First, we define the `Evidence` interface type. The `x/evidence` module may implement
its own types that can be used by many chains (e.g. `CounterFactualEvidence`).
In addition, other modules may implement their own `Evidence` types in a similar
manner in which governance is extensible. It is important to note any concrete
type implementing the `Evidence` interface may include arbitrary fields such as
an infraction time. We want the `Evidence` type to remain as flexible as possible.

However, when submitting evidence to the `x/evidence` module, it must be submitted
as an `Infraction` which includes mandatory fields outlined below. The `Infraction`
type must include the validator's consensus address, which should be known by the
`x/slashing` module, the height at which the infraction occurred and the validator's
power at same height in which the infraction occurred.

```go
type Evidence interface {
cwgoes marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, we could potentially add Verify and Hash but I wonder what Verify would look like?

Copy link
Contributor

Choose a reason for hiding this comment

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

Route() string
Type() string
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add a short comment on the type

Suggested change
Type() string
// Evidence type. Each of the types might have custom slashing penalties values defined by governance
Type() string

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why is this necessary?

ValidateBasic() sdk.Error
String() string
}

type Infraction struct {
Evidence

ConsensusAddress sdk.ConsAddress
InfractionHeight int64
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
Power int64
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
}
```

### Routing & Handling

Each `Evidence` type must map to a specific unique route and be registered with
the `x/evidence` module. It accomplishes this through the `Router` implementation.

```go
type Router interface {
AddRoute(r string, h Handler) (rtr Router)
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
HasRoute(r string) bool
GetRoute(path string) (h Handler)
Seal()
}
```

Upon successful routing through the `x/evidence` module, the `Evidence` type
is passed through a `Handler`. This `Handler` is responsible for executing all
corresponding business logic necessary for verifying the evidence. If no error
is returned, the `Evidence` is considered valid.

```go
type Handler func(ctx sdk.Context, evidence Evidence) sdk.Error
```

### Submission

Assuming the `Evidence` is valid, the corresponding slashing penalty is invoked
for the `Evidence`'s `Type`. Keep in mind the slashing penalty for any `Type` can
be configured through governance.

```go
type MsgSubmitInfraction struct {
Infraction
}

func handleMsgSubmitInfraction(ctx sdk.Context, keeper Keeper, msg MsgSubmitEvidence) sdk.Result {
if err := keeper.SubmitInfraction(ctx, msg.Infraction); err != nil {
return err.Result()
}

// emit events...

return sdk.Result{
// ...
}
}
```

The `x/evidence` module's keeper is responsible for matching the `Evidence` against
the module's router. Upon success the validator is slashed and the infraction is
persisted. In addition, the validator is jailed is the `Evidence` type is configured
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
to do so.

```go
func (k Keeper) SubmitInfraction(ctx sdk.Context, infraction Infraction) sdk.Error {
handler := keeper.router.GetRoute(infraction.Evidence.Route())
if err := handler(cacheCtx, infraction.Evidence); err != nil {
return ErrInvalidEvidence(keeper.codespace, err.Result().Log)
}

penalty := keeper.GetSlashingPenalty(ctx, infraction.Evidence.Type())
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

keeper.stakingKeeper.Slash(
ctx,
infraction.ConsensusAddress,
infraction.InfractionHeight,
infraction.Power,
penalty.SlashFraction,
)

if penalty.Jailable {
keeper.stakingKeeper.Jail(ctx, infraction.ConsensusAddress)
}

keeper.setInfraction(ctx, infraction)
}
```

### Genesis

We require the the `x/evidence` module's keeper to keep an internal persistent
mapping between `Evidence` types and slashing penalties represented as `InfractionPenalty`.

```go
var slashingPenaltyPrefixKey = []byte{0x01}

type InfractionPenalty struct {
EvidenceType string
Penalty sdk.Dec
}

func GetSlashingPenaltyKey(evidenceType string) []byte {
return append(slashingPenaltyPrefixKey, []byte(evidenceType)...)
}

func (k Keeper) GetSlashingPenalty(ctx sdk.Context, evidenceType string) sdk.Dec {
store := ctx.KVStore(k.storeKey)

bz := store.Get(GetSlashingPenaltyKey(evidenceType))
if len(bz) == 0 {
return sdk.ZeroDec()
}

var ip InfractionPenalty
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &ip)

return ip.Penalty
}
```

Finally, we need to represent the genesis state of the `x/evidence` module. The
module only needs a list of all submitted valid infractions and the infraction
penalties which we represent through parameters managed by the `x/params` module.

```go
type PenaltyParam struct {
SlashFraction sdk.Dec
Jailable bool
}

type PenaltyParams struct {
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
// A series of misbehaviour penalties all of which are of type PenaltyParam
// and these can individually be changed through a governance parameter change
// proposal.
}

type GenesisState struct {
Params PenaltyParams
Infractions []Infraction
}
```

## Consequences

### Positive

- Allows the state machine to process equivocations submitted on-chain and penalize
validators based on agreed upon slashing parameters
- Does not solely rely on Tendermint to submit evidence

### Negative

- No easy way to introduce new evidence types through governance on a live chain
cwgoes marked this conversation as resolved.
Show resolved Hide resolved
due to the inability to introduce the new evidence type's corresponding handler

### Neutral

- Should we persist infractions indefinitely? Or should we rather rely on events?
Copy link
Contributor

Choose a reason for hiding this comment

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

At the moment they are persisted by F1 in any case, since they need to be iterated over for later reward calculations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was mainly in regards to the state the x/evidence module persists. Do you see that as redundant?

Copy link
Contributor

Choose a reason for hiding this comment

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

It depends on what infractions might need to be looked-up for, I suppose.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's persist them unless you see a reason not to.


## References
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should also add ICS03 as a reference here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

2 or 3? As the link above routes to ics-003

Copy link
Collaborator

Choose a reason for hiding this comment

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

ICS02 sorry


- [ICS](https://github.com/cosmos/ics)
- [IBC Architecture](https://github.com/cosmos/ics/blob/master/ibc/1_IBC_ARCHITECTURE.md)