You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
10 KiB

  1. ---
  2. order: 4
  3. title: Tendermint's expected behavior
  4. ---
  5. # Tendermint's expected behavior
  6. ## Valid method call sequences
  7. This section describes what the Application can expect from Tendermint.
  8. The Tendermint consensus algorithm is designed to protect safety under any network conditions, as long as
  9. less than 1/3 of validators' voting power is byzantine. Most of the time, though, the network will behave synchronously and there will be no byzantine process. In these frequent, benign conditions:
  10. * Tendermint will decide in round 0;
  11. * `PrepareProposal` will be called exactly once at the proposer process of round 0, height _h_;
  12. * `ProcessProposal` will be called exactly once at all processes except the proposer of round 0, and
  13. will return _accept_ in its `Response*`;
  14. * `ExtendVote` will be called exactly once at all processes
  15. * `VerifyVoteExtension` will be called _n-1_ times at each validator process, where _n_ is the number of validators; and
  16. * `FinalizeBlock` will be finally called at all processes at the end of height _h_, conveying the same prepared
  17. block that all calls to `PrepareProposal` and `ProcessProposal` had previously reported for height _h_.
  18. However, the Application logic must be ready to cope with any possible run of Tendermint for a given
  19. height, including bad periods (byzantine proposers, network being asynchronous).
  20. In these cases, the sequence of calls to ABCI++ methods may not be so straighforward, but
  21. the Application should still be able to handle them, e.g., without crashing.
  22. The purpose of this section is to define what these sequences look like an a precise way.
  23. As mentioned in the [Basic Concepts](abci++_basic_concepts_002_draft.md) section, Tendermint
  24. acts as a client of ABCI++ and the Application acts as a server. Thus, it is up to Tendermint to
  25. determine when and in which order the different ABCI++ methods will be called. A well-written
  26. Application design should consider _any_ of these possible sequences.
  27. The following grammar, written in case-sensitive Augmented Backus–Naur form (ABNF, specified
  28. in [IETF rfc7405](https://datatracker.ietf.org/doc/html/rfc7405)), specifies all possible
  29. sequences of calls to ABCI++, taken by a correct process, across all heights from the genesis block,
  30. including recovery runs, from the point of view of the Application.
  31. ```abnf
  32. start = clean-start / recovery
  33. clean-start = init-chain [state-sync] consensus-exec
  34. state-sync = *state-sync-attempt success-sync info
  35. state-sync-attempt = offer-snapshot *apply-chunk
  36. success-sync = offer-snapshot 1*apply-chunk
  37. recovery = info *consensus-replay consensus-exec
  38. consensus-replay = decide
  39. consensus-exec = (inf)consensus-height
  40. consensus-height = *consensus-round decide
  41. consensus-round = proposer / non-proposer
  42. proposer = prepare-proposal extend-proposer
  43. extend-proposer = *got-vote [extend-vote] *got-vote
  44. non-proposer = *got-vote [extend-non-proposer] *got-vote
  45. extend-non-proposer = process-proposal *got-vote [extend-vote]
  46. init-chain = %s"<InitChain>"
  47. offer-snapshot = %s"<OfferSnapshot>"
  48. apply-chunk = %s"<ApplySnapshotChunk>"
  49. info = %s"<Info>"
  50. prepare-proposal = %s"<PrepareProposal>"
  51. process-proposal = %s"<ProcessProposal>"
  52. extend-vote = %s"<ExtendVote>"
  53. got-vote = %s"<VerifyVoteExtension>"
  54. decide = %s"<FinalizeBlock>"
  55. ```
  56. >**TODO** Still hesitating... introduce _n_ as total number of validators, so that we can bound the occurrences of
  57. >`got-vote` in a round.
  58. We have kept some of the ABCI++ methods out of the grammar, in order to keep it as clear and concise as possible.
  59. A common reason for keeping all these methods out is that they all can be called at any point in a sequence defined
  60. by the grammar above. Other reasons depend on the method in question:
  61. * `Echo` and `Flush` are only used for debugging purposes. Further, their handling by the Application should be trivial.
  62. * `CheckTx` is detached from the main method call sequence that drives block execution.
  63. * `Query` provides read-only access to the current Application state, so handling it should also be independent from
  64. block execution.
  65. * Similarly, `ListSnapshots` and `LoadSnapshotChunk` provide read-only access to the Application's previously created
  66. snapshots (if any), and help populate the parameters of `OfferSnapshot` and `ApplySnapshotChunk` at a process performing
  67. state-sync while bootstrapping. Unlike `ListSnapshots` and `LoadSnapshotChunk`, both `OfferSnapshot`
  68. and `ApplySnapshotChunk` _are_ included in the grammar.
  69. Finally, method `Info` is a special case. The method's purpose is three-fold, it can be used
  70. 1. as part of handling an RPC call from an external client,
  71. 2. as a handshake between Tendermint and the Application upon recovery to check whether any blocks need
  72. to be replayed, and
  73. 3. at the end of _state-sync_ to verify that the correct state has been reached.
  74. We have left `Info`'s first purpose out of the grammar for the same reasons as all the others: it can happen
  75. at any time, and has nothing to do with the block execution sequence. The second and third purposes, on the other
  76. hand, are present in the grammar.
  77. Let us now examine the grammar line by line, providing further details.
  78. * When a process starts, it may do so for the first time or after a crash (it is recovering).
  79. >```abnf
  80. >start = clean-start / recovery
  81. >```
  82. * If the process is starting from scratch, Tendermint first calls `InitChain`, then it may optionally
  83. start a _state-sync_ mechanism to catch up with other processes. Finally, it enters normal
  84. consensus execution.
  85. >```abnf
  86. >clean-start = init-chain [state-sync] consensus-exec
  87. >```
  88. * In _state-sync_ mode, Tendermint makes one or more attempts at synchronizing the Application's state.
  89. At the beginning of each attempt, it offers the Application a snapshot found at another process.
  90. If the Application accepts the snapshop, at sequence of calls to `ApplySnapshotChunk` method follow
  91. to provide the Application with all the snapshots needed, in order to reconstruct the state locally.
  92. A successful attempt must provide at least one chunk via `ApplySnapshotChunk`.
  93. At the end of a successful attempt, Tendermint calls `Info` to make sure the recontructed state's
  94. _AppHash_ matches the one in the block header at the corresponding height.
  95. >```abnf
  96. >state-sync = *state-sync-attempt success-sync info
  97. >state-sync-attempt = offer-snapshot *apply-chunk
  98. >success-sync = offer-snapshot 1*apply-chunk
  99. >```
  100. * In recovery mode, Tendermint first calls `Info` to know from which height it needs to replay decisions
  101. to the Application. To replay a decision, Tendermint simply calls `FinalizeBlock` with the decided
  102. block at that height. After this, Tendermint enters nomal consensus execution.
  103. >```abnf
  104. >recovery = info *consensus-replay consensus-exec
  105. >consensus-replay = decide
  106. >```
  107. * The non-terminal `consensus-exec` is a key point in this grammar. It is an infinite sequence of
  108. consensus heights. The grammar is thus an
  109. [omega-grammar](https://dl.acm.org/doi/10.5555/2361476.2361481), since it produces infinite
  110. sequences of terminals (i.e., the API calls).
  111. >```abnf
  112. >consensus-exec = (inf)consensus-height
  113. >```
  114. * A consensus height consists of zero or more rounds before deciding via a call to `FinalizeBlock`.
  115. In each round, the sequence of method calls depends on whether the local process is the proposer or not.
  116. >```abnf
  117. >consensus-height = *consensus-round decide
  118. >consensus-round = proposer / non-proposer
  119. >```
  120. * If the local process is the proposer of the current round, Tendermint starts by calling `PrepareProposal`.
  121. No calls to methods related to vote extensions (`ExtendVote`, `VerifyVoteExtension`) can be called
  122. in the present round before `PrepareProposal`. Once `PrepareProposal` is called, calls to
  123. `ExtendVote` and `VerifyVoteExtension` can come in any order, although the former will be called
  124. at most once in this round.
  125. >```abnf
  126. >proposer = prepare-proposal extend-proposer
  127. >extend-proposer = *got-vote [extend-vote] *got-vote
  128. >```
  129. * If the local process is not the proposer of the current round, Tendermint will call `ProcessProposal`
  130. at most once. At most one call to `ExtendVote` can occur only after `ProcessProposal` is called.
  131. A number of calls to `VerifyVoteExtension` can occur in any order with respect to `ProcessProposal`
  132. and `ExtendVote` throughout the round.
  133. >```abnf
  134. >non-proposer = *got-vote [extend-non-proposer] *got-vote
  135. >extend-non-proposer = process-proposal *got-vote [extend-vote]
  136. >```
  137. * Finally, the grammar describes all its terminal symbols, which denote the different ABCI++ method calls that
  138. may appear in a sequence.
  139. >```abnf
  140. >init-chain = %s"<InitChain>"
  141. >offer-snapshot = %s"<OfferSnapshot>"
  142. >apply-chunk = %s"<ApplySnapshotChunk>"
  143. >info = %s"<Info>"
  144. >prepare-proposal = %s"<PrepareProposal>"
  145. >process-proposal = %s"<ProcessProposal>"
  146. >extend-vote = %s"<ExtendVote>"
  147. >got-vote = %s"<VerifyVoteExtension>"
  148. >decide = %s"<FinalizeBlock>"
  149. >```
  150. ## Adapting existing Applications that use ABCI
  151. In some cases, an existing Application using the legacy ABCI may need to be adapted to work with ABCI++
  152. with as minimal changes as possible. In this case, of course, ABCI++ will not provide any advange with respect
  153. to the existing implementation, but will keep the same guarantees already provided by ABCI.
  154. Here is how ABCI++ methods should be implemented.
  155. First of all, all the methods that did not change from ABCI to ABCI++, namely `Echo`, `Flush`, `Info`, `InitChain`,
  156. `Query`, `CheckTx`, `ListSnapshots`, `LoadSnapshotChunk`, `OfferSnapshot`, and `ApplySnapshotChunk`, do not need
  157. to undergo any changes in their implementation.
  158. As for the new methods:
  159. * `PrepareProposal` should set `ResponsePrepareProposal.modified_tx` to _false_ and return.
  160. * `ProcessProposal` should set `ResponseProcessProposal.accept` to _true_ and return.
  161. * `ExtendVote` should set `ResponseExtendVote.extension` to an empty byte array and return.
  162. * `VerifyVoteExtension` should set `ResponseVerifyVoteExtension.accept` to _true_ if the extension is an empty byte array
  163. and _false_ otherwise, then return.
  164. * `FinalizeBlock` should coalesce the implementation of methods `BeginBlock`, `DeliverTx`, `EndBlock`, and `Commit`.
  165. The logic extracted from `DeliverTx` should be wrappped by a loop that will execute as many times as
  166. transactions exist in `RequestFinalizeBlock.tx`.