mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-19 21:56:22 +00:00
Merge pull request from GHSA-f3w5-v9xx-rp8p
* add time warping lunatic attack test * create too high and connecton refused errors and add to the light client provider * add height check to provider * introduce block lag * add detection logic for processing forward lunatic attack * add node-side verification logic * clean up tests and formatting * update adr's * update testing * fix fetching the latest block * format * update changelog * implement suggestions * modify ADR's * format * clean up node evidence verification
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
* 14-08-2020: Introduce light traces (listed now as an alternative approach)
|
||||
* 20-08-2020: Light client produces evidence when detected instead of passing to full node
|
||||
* 16-09-2020: Post-implementation revision
|
||||
* 15-03-2020: Ammends for the case of a forward lunatic attack
|
||||
|
||||
### Glossary of Terms
|
||||
|
||||
@@ -106,8 +107,10 @@ This is done with:
|
||||
```golang
|
||||
func (c *Client) examineConflictingHeaderAgainstTrace(
|
||||
trace []*types.LightBlock,
|
||||
divergentHeader *types.SignedHeader,
|
||||
source provider.Provider, now time.Time) ([]*types.LightBlock, *types.LightBlock, error)
|
||||
targetBlock *types.LightBlock,
|
||||
source provider.Provider,
|
||||
now time.Time,
|
||||
) ([]*types.LightBlock, *types.LightBlock, error)
|
||||
```
|
||||
|
||||
which performs the following
|
||||
@@ -117,16 +120,21 @@ because witnesses cannot be added and removed after the client is initialized. B
|
||||
as a sanity check. If this fails we have to drop the witness.
|
||||
|
||||
2. Querying and verifying the witness's headers using bisection at the same heights of all the
|
||||
intermediary headers of the primary (In the above example this is A, B, C, D, F, H). If bisection fails or the witness stops responding then
|
||||
we can call the witness faulty and drop it.
|
||||
intermediary headers of the primary (In the above example this is A, B, C, D, F, H). If bisection fails
|
||||
or the witness stops responding then we can call the witness faulty and drop it.
|
||||
|
||||
3. We eventually reach a verified header by the witness which is not the same as the intermediary header (In the above example this is E).
|
||||
This is the point of bifurcation (This could also be the last header).
|
||||
3. We eventually reach a verified header by the witness which is not the same as the intermediary header
|
||||
(In the above example this is E). This is the point of bifurcation (This could also be the last header).
|
||||
|
||||
4. There is a unique case where the trace that is being examined against has blocks that have a greater
|
||||
height than the targetBlock. This can occur as part of a forward lunatic attack where the primary has
|
||||
provided a light block that has a height greater than the head of the chain (see Appendix B). In this
|
||||
case, the light client will verify the sources blocks up to the targetBlock and return the block in the
|
||||
trace that is directly after the targetBlock in height as the `ConflictingBlock`
|
||||
|
||||
This function then returns the trace of blocks from the witness node between the common header and the
|
||||
divergent header of the primary as it
|
||||
is likely as seen in the example to the right below that multiple headers where required in order to
|
||||
verify the divergent one. This trace will
|
||||
divergent header of the primary as it is likely, as seen in the example to the right, that multiple
|
||||
headers where required in order to verify the divergent one. This trace will
|
||||
be used later (as is also described later in this document).
|
||||
|
||||

|
||||
@@ -225,3 +233,22 @@ would be validators that currently still have something staked.
|
||||
Not only this but there was a large degree of extra computation required in storing all
|
||||
the currently staked validators that could possibly fall into the group of being
|
||||
a phantom validator. Given this, it was removed.
|
||||
|
||||
## Appendix B
|
||||
|
||||
A unique flavor of lunatic attack is a forward lunatic attack. This is where a malicious
|
||||
node provides a header with a height greater than the height of the blockchain. Thus there
|
||||
are no witnesses capable of rebutting the malicious header. Such an attack will also
|
||||
require an accomplice, i.e. at least one other witness to also return the same forged header.
|
||||
Although such attacks can be any arbitrary height ahead, they must still remain within the
|
||||
clock drift of the light clients real time. Therefore, to detect such an attack, a light
|
||||
client will wait for a time
|
||||
|
||||
```
|
||||
2 * MAX_CLOCK_DRIFT + LAG
|
||||
```
|
||||
|
||||
for a witness to provide the latest block it has. Given the time constraints, if the witness
|
||||
is operating at the head of the blockchain, it will have a header with an earlier height but
|
||||
a later timestamp. This can be used to prove that the primary has submitted a lunatic header
|
||||
which violates monotonically increasing time.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
- 04/09/2020: Initial Draft (Unabridged)
|
||||
- 07/09/2020: First Version
|
||||
- 13.03.21: Ammendment to accomodate forward lunatic attack
|
||||
|
||||
## Scope
|
||||
|
||||
@@ -159,7 +160,7 @@ For `LightClientAttack`
|
||||
|
||||
- Fetch the common signed header and val set from the common height and use skipping verification to verify the conflicting header
|
||||
|
||||
- Fetch the trusted signed header at the same height as the conflicting header and compare with the conflicting header to work out which type of attack it is and in doing so return the malicious validators.
|
||||
- Fetch the trusted signed header at the same height as the conflicting header and compare with the conflicting header to work out which type of attack it is and in doing so return the malicious validators. NOTE: If the node doesn't have the signed header at the height of the conflicting header, it instead fetches the latest header it has and checks to see if it can prove the evidence based on a violation of header time. This is known as forward lunatic attack.
|
||||
|
||||
- If equivocation, return the validators that signed for the commits of both the trusted and signed header
|
||||
|
||||
@@ -167,7 +168,11 @@ For `LightClientAttack`
|
||||
|
||||
- If amnesia, return no validators (since we can't know which validators are malicious). This also means that we don't currently send amnesia evidence to the application, although we will introduce more robust amnesia evidence handling in future Tendermint Core releases
|
||||
|
||||
- For each validator, check the look up table to make sure there already isn't evidence against this validator
|
||||
- Check that the hashes of the conflicting header and the trusted header are different
|
||||
|
||||
- In the case of a forward lunatic attack, where the trusted header height is less than the conflicting header height, the node checks that the time of the trusted header is later than the time of conflicting header. This proves that the conflicting header breaks monotonically increasing time. If the node doesn't have a trusted header with a later time then it is unable to validate the evidence for now.
|
||||
|
||||
- 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:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user