github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/docs/architecture/adr-009-evidence-module.md (about) 1 # ADR 009: Evidence Module 2 3 ## Changelog 4 5 - 2019 July 31: Initial draft 6 - 2019 October 24: Initial implementation 7 8 ## Status 9 10 Accepted 11 12 ## Context 13 14 In order to support building highly secure, robust and interoperable blockchain 15 applications, it is vital for the Cosmos SDK to expose a mechanism in which arbitrary 16 evidence can be submitted, evaluated and verified resulting in some agreed upon 17 penalty for any misbehavior committed by a validator, such as equivocation (double-voting), 18 signing when unbonded, signing an incorrect state transition (in the future), etc. 19 Furthermore, such a mechanism is paramount for any 20 [IBC](https://github.com/cosmos/ics/blob/master/ibc/1_IBC_ARCHITECTURE.md) or 21 cross-chain validation protocol implementation in order to support the ability 22 for any misbehavior to be relayed back from a collateralized chain to a primary 23 chain so that the equivocating validator(s) can be slashed. 24 25 ## Decision 26 27 We will implement an evidence module in the Cosmos SDK supporting the following 28 functionality: 29 30 - Provide developers with the abstractions and interfaces necessary to define 31 custom evidence messages, message handlers, and methods to slash and penalize 32 accordingly for misbehavior. 33 - Support the ability to route evidence messages to handlers in any module to 34 determine the validity of submitted misbehavior. 35 - Support the ability, through governance, to modify slashing penalties of any 36 evidence type. 37 - Querier implementation to support querying params, evidence types, params, and 38 all submitted valid misbehavior. 39 40 ### Types 41 42 First, we define the `Evidence` interface type. The `x/evidence` module may implement 43 its own types that can be used by many chains (e.g. `CounterFactualEvidence`). 44 In addition, other modules may implement their own `Evidence` types in a similar 45 manner in which governance is extensible. It is important to note any concrete 46 type implementing the `Evidence` interface may include arbitrary fields such as 47 an infraction time. We want the `Evidence` type to remain as flexible as possible. 48 49 When submitting evidence to the `x/evidence` module, the concrete type must provide 50 the validator's consensus address, which should be known by the `x/slashing` 51 module (assuming the infraction is valid), the height at which the infraction 52 occurred and the validator's power at same height in which the infraction occurred. 53 54 ```go 55 type Evidence interface { 56 Route() string 57 Type() string 58 String() string 59 Hash() HexBytes 60 ValidateBasic() error 61 62 // The consensus address of the malicious validator at time of infraction 63 GetConsensusAddress() ConsAddress 64 65 // Height at which the infraction occurred 66 GetHeight() int64 67 68 // The total power of the malicious validator at time of infraction 69 GetValidatorPower() int64 70 71 // The total validator set power at time of infraction 72 GetTotalPower() int64 73 } 74 ``` 75 76 ### Routing & Handling 77 78 Each `Evidence` type must map to a specific unique route and be registered with 79 the `x/evidence` module. It accomplishes this through the `Router` implementation. 80 81 ```go 82 type Router interface { 83 AddRoute(r string, h Handler) Router 84 HasRoute(r string) bool 85 GetRoute(path string) Handler 86 Seal() 87 } 88 ``` 89 90 Upon successful routing through the `x/evidence` module, the `Evidence` type 91 is passed through a `Handler`. This `Handler` is responsible for executing all 92 corresponding business logic necessary for verifying the evidence as valid. In 93 addition, the `Handler` may execute any necessary slashing and potential jailing. 94 Since slashing fractions will typically result from some form of static functions, 95 allow the `Handler` to do this provides the greatest flexibility. An example could 96 be `k * evidence.GetValidatorPower()` where `k` is an on-chain parameter controlled 97 by governance. The `Evidence` type should provide all the external information 98 necessary in order for the `Handler` to make the necessary state transitions. 99 If no error is returned, the `Evidence` is considered valid. 100 101 ```go 102 type Handler func(Context, Evidence) error 103 ``` 104 105 ### Submission 106 107 `Evidence` is submitted through a `MsgSubmitEvidence` message type which is internally 108 handled by the `x/evidence` module's `SubmitEvidence`. 109 110 ```go 111 type MsgSubmitEvidence struct { 112 Evidence 113 } 114 115 func handleMsgSubmitEvidence(ctx Context, keeper Keeper, msg MsgSubmitEvidence) Result { 116 if err := keeper.SubmitEvidence(ctx, msg.Evidence); err != nil { 117 return err.Result() 118 } 119 120 // emit events... 121 122 return Result{ 123 // ... 124 } 125 } 126 ``` 127 128 The `x/evidence` module's keeper is responsible for matching the `Evidence` against 129 the module's router and invoking the corresponding `Handler` which may include 130 slashing and jailing the validator. Upon success, the submitted evidence is persisted. 131 132 ```go 133 func (k Keeper) SubmitEvidence(ctx Context, evidence Evidence) error { 134 handler := keeper.router.GetRoute(evidence.Route()) 135 if err := handler(ctx, evidence); err != nil { 136 return ErrInvalidEvidence(keeper.codespace, err) 137 } 138 139 keeper.setEvidence(ctx, evidence) 140 return nil 141 } 142 ``` 143 144 ### Genesis 145 146 Finally, we need to represent the genesis state of the `x/evidence` module. The 147 module only needs a list of all submitted valid infractions and any necessary params 148 for which the module needs in order to handle submitted evidence. The `x/evidence` 149 module will naturally define and route native evidence types for which it'll most 150 likely need slashing penalty constants for. 151 152 ```go 153 type GenesisState struct { 154 Params Params 155 Infractions []Evidence 156 } 157 ``` 158 159 ## Consequences 160 161 ### Positive 162 163 - Allows the state machine to process misbehavior submitted on-chain and penalize 164 validators based on agreed upon slashing parameters. 165 - Allows evidence types to be defined and handled by any module. This further allows 166 slashing and jailing to be defined by more complex mechanisms. 167 - Does not solely rely on Tendermint to submit evidence. 168 169 ### Negative 170 171 - No easy way to introduce new evidence types through governance on a live chain 172 due to the inability to introduce the new evidence type's corresponding handler 173 174 ### Neutral 175 176 - Should we persist infractions indefinitely? Or should we rather rely on events? 177 178 ## References 179 180 - [ICS](https://github.com/cosmos/ics) 181 - [IBC Architecture](https://github.com/cosmos/ics/blob/master/ibc/1_IBC_ARCHITECTURE.md) 182 - [Tendermint Fork Accountability](https://github.com/tendermint/spec/blob/7b3138e69490f410768d9b1ffc7a17abc23ea397/spec/consensus/fork-accountability.md)