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