github.com/number571/tendermint@v0.34.11-gost/docs/architecture/adr-047-handling-evidence-from-light-client.md (about) 1 # ADR 047: Handling evidence from light client 2 3 ## Changelog 4 * 18-02-2020: Initial draft 5 * 24-02-2020: Second version 6 * 13-04-2020: Add PotentialAmnesiaEvidence and a few remarks 7 * 31-07-2020: Remove PhantomValidatorEvidence 8 * 14-08-2020: Introduce light traces (listed now as an alternative approach) 9 * 20-08-2020: Light client produces evidence when detected instead of passing to full node 10 * 16-09-2020: Post-implementation revision 11 * 15-03-2020: Ammends for the case of a forward lunatic attack 12 13 ### Glossary of Terms 14 15 - a `LightBlock` is the unit of data that a light client receives, verifies and stores. 16 It is composed of a validator set, commit and header all at the same height. 17 - a **Trace** is seen as an array of light blocks across a range of heights that were 18 created as a result of skipping verification. 19 - a **Provider** is a full node that a light client is connected to and serves the light 20 client signed headers and validator sets. 21 - `VerifySkipping` (sometimes known as bisection or verify non-adjacent) is a method the 22 light client uses to verify a target header from a trusted header. The process involves verifying 23 intermediate headers in between the two by making sure that 1/3 of the validators that signed 24 the trusted header also signed the untrusted one. 25 - **Light Bifurcation Point**: If the light client was to run `VerifySkipping` with two providers 26 (i.e. a primary and a witness), the bifurcation point is the height that the headers 27 from each of these providers are different yet valid. This signals that one of the providers 28 may be trying to fool the light client. 29 30 ## Context 31 32 The bisection method of header verification used by the light client exposes 33 itself to a potential attack if any block within the light clients trusted period has 34 a malicious group of validators with power that exceeds the light clients trust level 35 (default is 1/3). To improve light client (and overall network) security, the light 36 client has a detector component that compares the verified header provided by the 37 primary against witness headers. This ADR outlines the process of mitigating attacks 38 on the light client by using witness nodes to cross reference with. 39 40 ## Alternative Approaches 41 42 A previously discussed approach to handling evidence was to pass all the data that the 43 light client had witnessed when it had observed diverging headers for the full node to 44 process.This was known as a light trace and had the following structure: 45 46 ```go 47 type ConflictingHeadersTrace struct { 48 Headers []*types.SignedHeader 49 } 50 ``` 51 52 This approach has the advantage of not requiring as much processing on the light 53 client side in the event that an attack happens. Although, this is not a significant 54 difference as the light client would in any case have to validate all the headers 55 from both witness and primary. Using traces would consume a large amount of bandwidth 56 and adds a DDOS vector to the full node. 57 58 59 ## Decision 60 61 The light client will be divided into two components: a `Verifier` (either sequential or 62 skipping) and a `Detector` (see [Informal's Detector](https://github.com/informalsystems/tendermint-rs/blob/master/docs/spec/lightclient/detection/detection.md)) 63 . The detector will take the trace of headers from the primary and check it against all 64 witnesses. For a witness with a diverging header, the detector will first verify the header 65 by bisecting through all the heights defined by the trace that the primary provided. If valid, 66 the light client will trawl through both traces and find the point of bifurcation where it 67 can proceed to extract any evidence (as is discussed in detail later). 68 69 Upon successfully detecting the evidence, the light client will send it to both primary and 70 witness before halting. It will not send evidence to other peers nor continue to verify the 71 primary's header against any other header. 72 73 74 ## Detailed Design 75 76 The verification process of the light client will start from a trusted header and use a bisectional 77 algorithm to verify up to a header at a given height. This becomes the verified header (does not 78 mean that it is trusted yet). All headers that were verified in between are cached and known as 79 intermediary headers and the entire array is sometimes referred to as a trace. 80 81 The light client's detector then takes all the headers and runs the detect function. 82 83 ```golang 84 func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Time) error 85 ``` 86 87 The function takes the last header it received, the target header and compares it against all the witnesses 88 it has through the following function: 89 90 ```golang 91 func (c *Client) compareNewHeaderWithWitness(errc chan error, h *types.SignedHeader, 92 witness provider.Provider, witnessIndex int) 93 ``` 94 95 The err channel is used to send back all the outcomes so that they can be processed in parallel. 96 Invalid headers result in dropping the witness, lack of response or not having the headers is ignored 97 just as headers that have the same hash. Headers, however, 98 of a different hash then trigger the detection process between the primary and that particular witness. 99 100 This begins with verification of the witness's header via skipping verification which is run in tande 101 with locating the Light Bifurcation Point 102 103  104 105 This is done with: 106 107 ```golang 108 func (c *Client) examineConflictingHeaderAgainstTrace( 109 trace []*types.LightBlock, 110 targetBlock *types.LightBlock, 111 source provider.Provider, 112 now time.Time, 113 ) ([]*types.LightBlock, *types.LightBlock, error) 114 ``` 115 116 which performs the following 117 118 1. Checking that the trusted header is the same. Currently, they should not theoretically be different 119 because witnesses cannot be added and removed after the client is initialized. But we do this any way 120 as a sanity check. If this fails we have to drop the witness. 121 122 2. Querying and verifying the witness's headers using bisection at the same heights of all the 123 intermediary headers of the primary (In the above example this is A, B, C, D, F, H). If bisection fails 124 or the witness stops responding then we can call the witness faulty and drop it. 125 126 3. We eventually reach a verified header by the witness which is not the same as the intermediary header 127 (In the above example this is E). This is the point of bifurcation (This could also be the last header). 128 129 4. There is a unique case where the trace that is being examined against has blocks that have a greater 130 height than the targetBlock. This can occur as part of a forward lunatic attack where the primary has 131 provided a light block that has a height greater than the head of the chain (see Appendix B). In this 132 case, the light client will verify the sources blocks up to the targetBlock and return the block in the 133 trace that is directly after the targetBlock in height as the `ConflictingBlock` 134 135 This function then returns the trace of blocks from the witness node between the common header and the 136 divergent header of the primary as it is likely, as seen in the example to the right, that multiple 137 headers where required in order to verify the divergent one. This trace will 138 be used later (as is also described later in this document). 139 140  141 142 Now, that an attack has been detected, the light client must form evidence to prove it. There are 143 three types of attacks that either the primary or witness could have done to try fool the light client 144 into verifying the wrong header: Lunatic, Equivocation and Amnesia. As the consequence is the same and 145 the data required to prove it is also very similar, we bundle these attack styles together in a single 146 evidence: 147 148 ```golang 149 type LightClientAttackEvidence struct { 150 ConflictingBlock *LightBlock 151 CommonHeight int64 152 } 153 ``` 154 155 The light client takes the stance of first suspecting the primary. Given the bifurcation point found 156 above, it takes the two divergent headers and compares whether the one from the primary is valid with 157 respect to the one from the witness. This is done by calling `isInvalidHeader()` which looks to see if 158 any one of the deterministically derived header fields differ from one another. This could be one of 159 `ValidatorsHash`, `NextValidatorsHash`, `ConsensusHash`, `AppHash`, and `LastResultsHash`. 160 In this case we know it's a Lunatic attack and to help the witness verify it we send the height 161 of the common header which is 1 in the example above or C in the example above that. If all these 162 hashes are the same then we can infer that it is either Equivocation or Amnesia. In this case we send 163 the height of the diverged headers because we know that the validator sets are the same, hence the 164 malicious nodes are still bonded at that height. In the example above, this is height 10 and the 165 example above that it is the height at E. 166 167 The light client now has the evidence and broadcasts it to the witness. 168 169 However, it could have been that the header the light client used from the witness against the primary 170 was forged, so before halting the light client swaps the process and thus suspects the witness and 171 uses the primary to create evidence. It calls `examineConflictingHeaderAgainstTrace` this time using 172 the witness trace found earlier. 173 If the primary was malicious it is likely that it will not respond but if it is innocent then the 174 light client will produce the same evidence but this time the conflicting 175 block will come from the witness node instead of the primary. The evidence is then formed and sent to 176 the primary node. 177 178 This then ends the process and the verify function that was called at the start returns the error to 179 the user. 180 181 For a detailed overview of how each of these three attacks can be conducted please refer to the 182 [fork accountability spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client/accountability.md). 183 184 ## Full Node Verification 185 186 When a full node receives evidence from the light client it will need to verify 187 it for itself before gossiping it to peers and trying to commit it on chain. This process is outlined 188 in [ADR-059](https://github.com/number571/tendermint/blob/master/docs/architecture/adr-059-evidence-composition-and-lifecycle.md). 189 190 ## Status 191 192 Implemented 193 194 ## Consequences 195 196 ### Positive 197 198 * Light client has increased security against Lunatic, Equivocation and Amnesia attacks. 199 * Do not need intermediate data structures to encapsulate the malicious behavior 200 * Generalized evidence makes the code simpler 201 202 ### Negative 203 204 * Breaking change on the light client from versions 0.33.8 and below. Previous 205 versions will still send `ConflictingHeadersEvidence` but it won't be recognized 206 by the full node. Light clients will however still refuse the header and shut down. 207 * Amnesia attacks although detected, will not be able to be punished as it is not 208 clear from the current information which nodes behaved maliciously. 209 * Evidence module must handle both individual and grouped evidence. 210 211 ### Neutral 212 213 ## References 214 215 * [Fork accountability spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client/accountability.md) 216 * [ADR 056: Light client amnesia attacks](https://github.com/number571/tendermint/blob/master/docs/architecture/adr-056-light-client-amnesia-attacks.md) 217 * [ADR-059: Evidence Composition and Lifecycle](https://github.com/number571/tendermint/blob/master/docs/architecture/adr-059-evidence-composition-and-lifecycle.md) 218 * [Informal's Light Client Detector](https://github.com/informalsystems/tendermint-rs/blob/master/docs/spec/lightclient/detection/detection.md) 219 220 221 ## Appendix A 222 223 PhantomValidatorEvidence was used to capture when a validator that was still staked 224 (i.e. within the bonded period) but was not in the current validator set had voted for a block. 225 226 In later discussions it was argued that although possible to keep phantom validator 227 evidence, any case a phantom validator that could have the capacity to be involved 228 in fooling a light client would have to be aided by 1/3+ lunatic validators. 229 230 It would also be very unlikely that the new validators injected by the lunatic attack 231 would be validators that currently still have something staked. 232 233 Not only this but there was a large degree of extra computation required in storing all 234 the currently staked validators that could possibly fall into the group of being 235 a phantom validator. Given this, it was removed. 236 237 ## Appendix B 238 239 A unique flavor of lunatic attack is a forward lunatic attack. This is where a malicious 240 node provides a header with a height greater than the height of the blockchain. Thus there 241 are no witnesses capable of rebutting the malicious header. Such an attack will also 242 require an accomplice, i.e. at least one other witness to also return the same forged header. 243 Although such attacks can be any arbitrary height ahead, they must still remain within the 244 clock drift of the light clients real time. Therefore, to detect such an attack, a light 245 client will wait for a time 246 247 ``` 248 2 * MAX_CLOCK_DRIFT + LAG 249 ``` 250 251 for a witness to provide the latest block it has. Given the time constraints, if the witness 252 is operating at the head of the blockchain, it will have a header with an earlier height but 253 a later timestamp. This can be used to prove that the primary has submitted a lunatic header 254 which violates monotonically increasing time.