evidence: handling evidence from light client(s) (#4532)

Closes: #4530

This PR contains logic for both submitting an evidence by the light client (lite2 package) and receiving it on the Tendermint side (/broadcast_evidence RPC and/or EvidenceReactor#Receive). Upon receiving the ConflictingHeadersEvidence (introduced by this PR), the Tendermint validates it, then breaks it down into smaller pieces (DuplicateVoteEvidence, LunaticValidatorEvidence, PhantomValidatorEvidence, PotentialAmnesiaEvidence). Afterwards, each piece of evidence is verified against the state of the full node and added to the pool, from which it's reaped upon block creation.

* rpc/client: do not pass height param if height ptr is nil

* rpc/core: validate incoming evidence!

* only accept ConflictingHeadersEvidence if one

of the headers is committed from this full node's perspective

This simplifies the code. Plus, if there are multiple forks, we'll
likely to receive multiple ConflictingHeadersEvidence anyway.

* swap CommitSig with Vote in LunaticValidatorEvidence

Vote is needed to validate signature

* no need to embed client

http is a provider and should not be used as a client
This commit is contained in:
Anton Kaliaev
2020-04-22 11:29:05 +04:00
committed by GitHub
parent ae3d21cf71
commit 41c11ad2c1
31 changed files with 1833 additions and 476 deletions
@@ -3,6 +3,7 @@
## Changelog
* 18-02-2020: Initial draft
* 24-02-2020: Second version
* 13-04-2020: Add PotentialAmnesiaEvidence and a few remarks
## Context
@@ -26,6 +27,11 @@ type ConflictingHeadersEvidence struct {
}
```
_Remark_: Theoretically, only the header, which differs from what a full node
has, needs to be sent. But sending two headers a) makes evidence easily
verifiable b) simplifies the light client, which does not have query each
witness as to which header it possesses.
When a full node receives the `ConflictingHeadersEvidence` evidence, it should
a) validate it b) figure out if malicious behaviour is obvious (immediately
slashable) or the fork accountability protocol needs to be started.
@@ -34,7 +40,7 @@ slashable) or the fork accountability protocol needs to be started.
Check both headers are valid (`ValidateBasic`), have the same height, and
signed by 1/3+ of the validator set that the full node had at height
`H1.Height-1`.
`H1.Height`.
- Q: What if light client validator set is not equal to full node's validator
set (i.e. from full node's point of view both headers are not properly signed;
@@ -53,6 +59,9 @@ signed by 1/3+ of the validator set that the full node had at height
### Figuring out if malicious behaviour is immediately slashable
Let's say H1 was committed from this full node's perspective (see Appendix A).
_If neither of the headers (H1 and H2) were committed from the full node's
perspective, the evidence must be rejected._
Intersect validator sets of H1 and H2.
* if there are signers(H2) that are not part of validators(H1), they misbehaved as
@@ -99,20 +108,23 @@ A new type of evidence needs to be created:
```go
type PhantomValidatorEvidence struct {
PubKey crypto.PubKey
Vote types.Vote
Header types.Header
Vote types.Vote
LastHeightValidatorWasInSet int64
}
```
It contains a validator's public key and a vote for a block, where this
validator is not part of the validator set.
validator is not part of the validator set. `LastHeightValidatorWasInSet`
indicates the last height validator was in the validator set.
### F5. Lunatic validator
```go
type LunaticValidatorEvidence struct {
Header types.Header
Vote types.Vote
Header types.Header
Vote types.Vote
InvalidHeaderField string
}
```
@@ -154,6 +166,26 @@ This includes `ValidatorsHash`, `NextValidatorsHash`, `ConsensusHash`,
for the block that was actually committed at the corresponding height, and
should thus be easy to check.
`InvalidHeaderField` contains the invalid field name. Note it's very likely
that multiple fields diverge, but it's faster to check just one. This field
MUST NOT be used to determine equality of `LunaticValidatorEvidence`.
### F2. Amnesia
```go
type PotentialAmnesiaEvidence struct {
VoteA types.Vote
VoteB types.Vote
}
```
To punish this attack, votes under question needs to be sent. Fork
accountability process should then use this evidence to request additional
information from offended validators and construct a new type of evidence to
punish those who conducted an amnesia attack.
See ADR-056 for the architecture of the fork accountability procedure.
## Status
Proposed.