github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/spec/light-client/detection/req-ibc-detection.md (about) 1 <!-- markdown-link-check-disable --> 2 3 # Requirements for Fork Detection in the IBC Context 4 5 ## What you need to know about IBC 6 7 In the following, I distilled what I considered relevant from 8 9 <https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics> 10 11 ### Components and their interface 12 13 #### Tendermint Blockchains 14 15 > I assume you know what that is. 16 17 #### An IBC/Tendermint correspondence 18 19 | IBC Term | Tendermint-RS Spec Term | Comment | 20 |----------|-------------------------| --------| 21 | `CommitmentRoot` | AppState | app hash | 22 | `ConsensusState` | Lightblock | not all fields are there. NextValidator is definitly needed | 23 | `ClientState` | latest light block + configuration parameters (e.g., trusting period + `frozenHeight` | NextValidators missing; what is `proofSpecs`?| 24 | `frozenHeight` | height of fork | set when a fork is detected | 25 | "would-have-been-fooled" | light node fork detection | light node may submit proof of fork to IBC component to halt it | 26 | `Height` | (no epochs) | (epoch,height) pair in lexicographical order (`compare`) | 27 | `Header` | ~signed header | validatorSet explicit (no hash); nextValidators missing | 28 | `Evidence` | t.b.d. | definition unclear "which the light client would have considered valid". Data structure will need to change | 29 | `verify` | `ValidAndVerified` | signature does not match perfectly (ClientState vs. LightBlock) + in `checkMisbehaviourAndUpdateState` it is unclear whether it uses traces or goes to h1 and h2 in one step | 30 31 #### Some IBC links 32 33 - [QueryConsensusState](https://github.com/cosmos/cosmos-sdk/blob/2651427ab4c6ea9f81d26afa0211757fc76cf747/x/ibc/02-client/client/utils/utils.go#L68) 34 35 #### Required Changes in ICS 007 36 37 - `assert(height > 0)` in definition of `initialise` doesn't match 38 definition of `Height` as *(epoch,height)* pair. 39 40 - `initialise` needs to be updated to new data structures 41 42 - `clientState.frozenHeight` semantics seem not totally consistent in 43 document. E.g., `min` needs to be defined over optional value in 44 `checkMisbehaviourAndUpdateState`. Also, if you are frozen, why do 45 you accept more evidence. 46 47 - `checkValidityAndUpdateState` 48 - `verify`: it needs to be clarified that checkValidityAndUpdateState 49 does not perform "bisection" (as currently hinted in the text) but 50 performs a single step of "skipping verification", called, 51 `ValidAndVerified` 52 - `assert (header.height > clientState.latestHeight)`: no old 53 headers can be installed. This might be OK, but we need to check 54 interplay with misbehavior 55 - clienstState needs to be updated according to complete data 56 structure 57 58 - `checkMisbehaviourAndUpdateState`: as evidence will contain a trace 59 (or two), the assertion that uses verify will need to change. 60 61 - ICS 002 states w.r.t. `queryChainConsensusState` that "Note that 62 retrieval of past consensus states by height (as opposed to just the 63 current consensus state) is convenient but not required." For 64 Tendermint fork detection, this seems to be a necessity. 65 66 - `Header` should become a lightblock 67 68 - `Evidence` should become `LightNodeProofOfFork` [LCV-DATA-POF.1] 69 70 - `upgradeClientState` what is the semantics (in particular what is 71 `height` doing?). 72 73 - `checkMisbehaviourAndUpdateState(cs: ClientState, PoF: 74 LightNodeProofOfFork)` needs to be adapted 75 76 #### Handler 77 78 A blockchain runs a **handler** that passively collects information about 79 other blockchains. It can be thought of a state machine that takes 80 input events. 81 82 - the state includes a lightstore (I guess called `ConsensusState` 83 in IBC) 84 85 - The following function is used to pass a header to a handler 86 87 ```go 88 type checkValidityAndUpdateState = (Header) => Void 89 ``` 90 91 For Tendermint, it will perform 92 `ValidandVerified`, that is, it does the trusting period check and the 93 +1/3 check (+2/3 for sequential headers). 94 If it verifies a header, it adds it to its lightstore, 95 if it does not pass verification it drops it. 96 Right now it only accepts a header more recent then the latest 97 header, 98 and drops older 99 ones or ones that could not be verified. 100 101 > The above paragraph captures what I believe what is the current 102 logic of `checkValidityAndUpdateState`. It may be subject to 103 change. E.g., maintain a lightstore with state (unverified, verified) 104 105 - The following function is used to pass "evidence" (this we 106 will need to make precise eventually) to a handler 107 108 ```go 109 type checkMisbehaviourAndUpdateState = (bytes) => Void 110 ``` 111 112 We have to design this, and the data that the handler can use to 113 check that there was some misbehavior (fork) in order react on 114 it, e.g., flagging a situation and 115 stop the protocol. 116 117 - The following function is used to query the light store (`ConsensusState`) 118 119 ```go 120 type queryChainConsensusState = (height: uint64) => ConsensusState 121 ``` 122 123 #### Relayer 124 125 - The active components are called **relayer**. 126 127 - a relayer contains light clients to two (or more?) blockchains 128 129 - the relayer send headers and data to the handler to invoke 130 `checkValidityAndUpdateState` and 131 `checkMisbehaviourAndUpdateState`. It may also query 132 `queryChainConsensusState`. 133 134 - multiple relayers may talk to one handler. Some relayers might be 135 faulty. We assume existence of at least single correct relayer. 136 137 ## Informal Problem Statement: Fork detection in IBC 138 139 ### Relayer requirement: Evidence for Handler 140 141 - The relayer should provide the handler with 142 "evidence" that there was a fork. 143 144 - The relayer can read the handler's consensus state. Thus the relayer can 145 feed the handler precisely the information the handler needs to detect a 146 fork. 147 What is this 148 information needs to be specified. 149 150 - The information depends on the verification the handler does. It 151 might be necessary to provide a bisection proof (list of 152 lightblocks) so that the handler can verify based on its local 153 lightstore a header *h* that is conflicting with a header *h'* in the 154 local lightstore, that is, *h != h'* and *h.Height = h'.Height* 155 156 ### Relayer requirement: Fork detection 157 158 Let's assume there is a fork at chain A. There are two ways the 159 relayer can figure that out: 160 161 1. as the relayer contains a light client for A, it also includes a fork 162 detector that can detect a fork. 163 164 2. the relayer may also detect a fork by observing that the 165 handler for chain A (on chain B) 166 is on a different branch than the relayer 167 168 - in both detection scenarios, the relayer should submit evidence to 169 full nodes of chain A where there is a fork. As we assume a fullnode 170 has a complete list of blocks, it is sufficient to send "Bucky's 171 evidence" (<https://github.com/tendermint/tendermint/issues/5083>), 172 that is, 173 - two lightblocks from different branches + 174 - a lightblock (perhaps just a height) from which both blocks 175 can be verified. 176 177 - in the scenario 2., the relayer must feed the A-handler (on chain B) 178 a proof of a fork on A so that chain B can react accordingly 179 180 ### Handler requirement 181 182 - there are potentially many relayers, some correct some faulty 183 184 - a handler cannot trust the information provided by the relayer, 185 but must verify 186 (Доверя́й, но проверя́й) 187 188 - in case of a fork, we accept that the handler temporarily stores 189 headers (tagged as verified). 190 191 - eventually, a handler should be informed 192 (`checkMisbehaviourAndUpdateState`) 193 by some relayer that it has 194 verified a header from a fork. Then the handler should do what is 195 required by IBC in this case (stop?) 196 197 ### Challenges in the handler requirement 198 199 - handlers and relayers work on different lightstores. In principle 200 the lightstore need not intersect in any heights a priori 201 202 - if a relayer sees a header *h* it doesn't know at a handler (`queryChainConsensusState`), the 203 relayer needs to 204 verify that header. If it cannot do it locally based on downloaded 205 and verified (trusted?) light blocks, it might need to use 206 `VerifyToTarget` (bisection). To call `VerifyToTarget` we might keep 207 *h* in the lightstore. If verification fails, we need to download the 208 "alternative" header of height *h.Height* to generate evidence for 209 the handler. 210 211 - we have to specify what precisely `queryChainConsensusState` 212 returns. It cannot be the complete lightstore. Is the last header enough? 213 214 - we would like to assume that every now and then (smaller than the 215 trusting period) a correct relayer checks whether the handler is on a 216 different branch than the relayer. 217 And we would like that this is enough to achieve 218 the Handler requirement. 219 220 - here the correctness argument would be easy if a correct relayer is 221 based on a light client with a *trusted* state, that is, a light 222 client who never changes its opinion about trusted. Then if such a 223 correct relayer checks-in with a handler, it will detect a fork, and 224 act in time. 225 226 - if the light client does not provide this interface, in the case of 227 a fork, we need some assumption about a correct relayer being on a 228 different branch than the handler, and we need such a relayer to 229 check-in not too late. Also 230 what happens if the relayer's light client is forced to roll-back 231 its lightstore? 232 Does it have to re-check all handlers? 233 234 ## On the interconnectedness of things 235 236 In the broader discussion of so-called "fork accountability" there are 237 several subproblems 238 239 - Fork detection 240 241 - Evidence creation and submission 242 243 - Isolating misbehaving nodes (and report them for punishment over abci) 244 245 ### Fork detection 246 247 The preliminary specification ./detection.md formalizes the notion of 248 a fork. Roughly, a fork exists if there are two conflicting headers 249 for the same height, where both are supported by bonded full nodes 250 (that have been validators in the near past, that is, within the 251 trusting period). We distinguish between *fork on the chain* where two 252 conflicting blocks are signed by +2/3 of the validators of that 253 height, and a *light client fork* where one of the conflicting headers 254 is not signed by +2/3 of the current height, but by +1/3 of the 255 validators of some smaller height. 256 257 In principle everyone can detect a fork 258 259 - ./detection talks about the Tendermint light client with a focus on 260 light nodes. A relayer runs such light clients and may detect 261 forks in this way 262 263 - in IBC, a relayer can see that a handler is on a conflicting branch 264 - the relayer should feed the handler the necessary information so 265 that it can halt 266 - the relayer should report the fork to a full node 267 268 ### Evidence creation and submission 269 270 - the information sent from the relayer to the handler could be called 271 evidence, but this is perhaps a bad idea because the information sent to a 272 full node can also be called evidence. But this evidence might still 273 not be enough as the full node might need to run the "fork 274 accountability" protocol to generate evidence in the form of 275 consensus messages. So perhaps we should 276 introduce different terms for: 277 278 - proof of fork for the handler (basically consisting of lightblocks) 279 - proof of fork for a full node (basically consisting of (fewer) lightblocks) 280 - proof of misbehavior (consensus messages) 281 282 ### Isolating misbehaving nodes 283 284 - this is the job of a full node. 285 286 - might be subjective in the future: the protocol depends on what the 287 full node believes is the "correct" chain. Right now we postulate 288 that every full node is on the correct chain, that is, there is no 289 fork on the chain. 290 291 - The full node figures out which nodes are 292 - lunatic 293 - double signing 294 - amnesic; **using the challenge response protocol** 295 296 - We do not punish "phantom" validators 297 - currently we understand a phantom validator as a node that 298 - signs a block for a height in which it is not in the 299 validator set 300 - the node is not part of the +1/3 of previous validators that 301 are used to support the header. Whether we call a validator 302 phantom might be subjective and depend on the header we 303 check against. Their formalization actually seems not so 304 clear. 305 - they can only do something if there are +1/3 faulty validators 306 that are either lunatic, double signing, or amnesic. 307 - abci requires that we only report bonded validators. So if a 308 node is a "phantom", we would need the check whether the node is 309 bonded, which currently is expensive, as it requires checking 310 blocks from the last three weeks. 311 - in the future, with state sync, a correct node might be 312 convinced by faulty nodes that it is in the validator set. Then 313 it might appear to be "phantom" although it behaves correctly 314 315 ## Next steps 316 317 > The following points are subject to my limited knowledge of the 318 > state of the work on IBC. Some/most of it might already exist and we 319 > will just need to bring everything together. 320 321 - "proof of fork for a full node" defines a clean interface between 322 fork detection and misbehavior isolation. So it should be produced 323 by protocols (light client, the relayer). So we should fix that 324 first. 325 326 - Given the problems of not having a light client architecture spec, 327 for the relayer we should start with this. E.g. 328 329 - the relayer runs light clients for two chains 330 - the relayer regularly queries consensus state of a handler 331 - the relayer needs to check the consensus state 332 - this involves local checks 333 - this involves calling the light client 334 - the relayer uses the light client to do IBC business (channels, 335 packets, connections, etc.) 336 - the relayer submits proof of fork to handlers and full nodes 337 338 > the list is definitely not complete. I think part of this 339 > (perhaps all) is 340 > covered by what Anca presented recently. 341 342 We will need to define what we expect from these components 343 344 - for the parts where the relayer talks to the handler, we need to fix 345 the interface, and what the handler does 346 347 - we write specs for these components.