diff --git a/docs/architecture/adr-059-evidence-composition-and-lifecycle.md b/docs/architecture/adr-059-evidence-composition-and-lifecycle.md index 5b86164b2..521dee257 100644 --- a/docs/architecture/adr-059-evidence-composition-and-lifecycle.md +++ b/docs/architecture/adr-059-evidence-composition-and-lifecycle.md @@ -4,7 +4,8 @@ - 04/09/2020: Initial Draft (Unabridged) - 07/09/2020: First Version -- 13.03.21: Ammendment to accomodate forward lunatic attack +- 13/03/2021: Ammendment to accomodate forward lunatic attack +- 29/06/2021: Add information about ABCI specific fields ## Scope @@ -111,6 +112,11 @@ We have two concrete types of evidence that fulfil this interface type LightClientAttackEvidence struct { ConflictingBlock *LightBlock CommonHeight int64 // the last height at which the primary provider and witness provider had the same header + + // abci specific information + ByzantineValidators []*Validator // validators in the validator set that misbehaved in creating the conflicting block + TotalVotingPower int64 // total voting power of the validator set at the common height + Timestamp time.Time // timestamp of the block at the common height } ``` where the `Hash()` is the hash of the header and commonHeight. @@ -121,6 +127,11 @@ Note: It was also discussed whether to include the commit hash which captures th type DuplicateVoteEvidence { VoteA *Vote VoteB *Vote + + // abci specific information + TotalVotingPower int64 + ValidatorPower int64 + Timestamp time.Time } ``` where the `Hash()` is the hash of the two votes @@ -174,19 +185,11 @@ For `LightClientAttack` - Lastly, for each validator, check the look up table to make sure there already isn't evidence against this validator -After verification we persist the evidence with the key `height/hash` to the pending evidence database in the evidence pool with the following format: +After verification we persist the evidence with the key `height/hash` to the pending evidence database in the evidence pool. -```go -type EvidenceInfo struct { - ev Evidence - time time.Time - validators []Validator - totalVotingPower int64 -} -``` - -`time`, `validators` and `totalVotingPower` are need to form the `abci.Evidence` that we send to the application layer. More in this to come later. +#### ABCI Evidence +Both evidence structures contain data (such as timestamp) that are necessary to be passed to the application but do not strictly constitute evidence of misbehaviour. As such, these fields are verified last. If any of these fields are invalid to a node i.e. they don't correspond with their state, nodes will reconstruct a new evidence struct from the existing fields and repopulate the abci specific fields with their own state data. #### Broadcasting and receiving evidence diff --git a/light/detector.go b/light/detector.go index 24972d6d8..873ebe859 100644 --- a/light/detector.go +++ b/light/detector.go @@ -394,9 +394,10 @@ func (c *Client) getTargetBlockOrLatest( // all the fields such that it is ready to be sent to a full node. func newLightClientAttackEvidence(conflicted, trusted, common *types.LightBlock) *types.LightClientAttackEvidence { ev := &types.LightClientAttackEvidence{ConflictingBlock: conflicted} + // We use the common height to indicate the form of the attack. // if this is an equivocation or amnesia attack, i.e. the validator sets are the same, then we - // return the height of the conflicting block else if it is a lunatic attack and the validator sets - // are not the same then we send the height of the common header. + // return the height of the conflicting block as the common height. If instead it is a lunatic + // attack and the validator sets are not the same then we send the height of the common header. if ev.ConflictingHeaderIsInvalid(trusted.Header) { ev.CommonHeight = common.Height ev.Timestamp = common.Time diff --git a/types/evidence.go b/types/evidence.go index 113004996..40ff85e5e 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -226,6 +226,9 @@ func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*Duplica // punishment of the malicious validators. There are three forms of attacks: Lunatic, Equivocation // and Amnesia. These attacks are exhaustive. You can find a more detailed overview of this at // tendermint/docs/architecture/adr-047-handling-evidence-from-light-client.md +// +// CommonHeight is used to indicate the type of attack. If the height is different to the conflicting block +// height, then nodes will treat this as of the Lunatic form, else it is of the Equivocation form. type LightClientAttackEvidence struct { ConflictingBlock *LightBlock CommonHeight int64