Browse Source

evidence: update ADR 59 and add comments to the use of common height (#6628)

pull/6631/head
Callum Waters 3 years ago
committed by GitHub
parent
commit
5ae3c24d55
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 14 deletions
  1. +15
    -12
      docs/architecture/adr-059-evidence-composition-and-lifecycle.md
  2. +3
    -2
      light/detector.go
  3. +3
    -0
      types/evidence.go

+ 15
- 12
docs/architecture/adr-059-evidence-composition-and-lifecycle.md View File

@ -4,7 +4,8 @@
- 04/09/2020: Initial Draft (Unabridged) - 04/09/2020: Initial Draft (Unabridged)
- 07/09/2020: First Version - 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 ## Scope
@ -111,6 +112,11 @@ We have two concrete types of evidence that fulfil this interface
type LightClientAttackEvidence struct { type LightClientAttackEvidence struct {
ConflictingBlock *LightBlock ConflictingBlock *LightBlock
CommonHeight int64 // the last height at which the primary provider and witness provider had the same header 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. 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 { type DuplicateVoteEvidence {
VoteA *Vote VoteA *Vote
VoteB *Vote VoteB *Vote
// abci specific information
TotalVotingPower int64
ValidatorPower int64
Timestamp time.Time
} }
``` ```
where the `Hash()` is the hash of the two votes 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 - 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:
```go
type EvidenceInfo struct {
ev Evidence
time time.Time
validators []Validator
totalVotingPower int64
}
```
After verification we persist the evidence with the key `height/hash` to the pending evidence database in the evidence pool.
`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 #### Broadcasting and receiving evidence


+ 3
- 2
light/detector.go View File

@ -394,9 +394,10 @@ func (c *Client) getTargetBlockOrLatest(
// all the fields such that it is ready to be sent to a full node. // all the fields such that it is ready to be sent to a full node.
func newLightClientAttackEvidence(conflicted, trusted, common *types.LightBlock) *types.LightClientAttackEvidence { func newLightClientAttackEvidence(conflicted, trusted, common *types.LightBlock) *types.LightClientAttackEvidence {
ev := &types.LightClientAttackEvidence{ConflictingBlock: conflicted} 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 // 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) { if ev.ConflictingHeaderIsInvalid(trusted.Header) {
ev.CommonHeight = common.Height ev.CommonHeight = common.Height
ev.Timestamp = common.Time ev.Timestamp = common.Time


+ 3
- 0
types/evidence.go View File

@ -226,6 +226,9 @@ func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*Duplica
// punishment of the malicious validators. There are three forms of attacks: Lunatic, Equivocation // 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 // 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 // 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 { type LightClientAttackEvidence struct {
ConflictingBlock *LightBlock ConflictingBlock *LightBlock
CommonHeight int64 CommonHeight int64


Loading…
Cancel
Save