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.