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.

402 lines
19 KiB

abci: Synchronize FinalizeBlock with the updated specification (#7983) This change set implements the most recent version of `FinalizeBlock`. # What does this change actually contain? * This change set is rather large but fear not! The majority of the files touched and changes are renaming `ResponseDeliverTx` to `ExecTxResult`. This should be a pretty inoffensive change since they're effectively the same type but with a different name. * The `execBlockOnProxyApp` was totally removed since it served as just a wrapper around the logic that is now mostly encapsulated within `FinalizeBlock` * The `updateState` helper function has been made a public method on `State`. It was being exposed as a shim through the testing infrastructure, so this seemed innocuous. * Tests already existed to ensure that the application received the `ByzantineValidators` and the `ValidatorUpdates`, but one was fixed up to ensure that `LastCommitInfo` was being sent across. * Tests were removed from the `psql` indexer that seemed to search for an event in the indexer that was not being created. # Questions for reviewers * We store this [ABCIResponses](https://github.com/tendermint/tendermint/blob/5721a13ab1f4479f9807f449f0bf5c536b9a05f2/proto/tendermint/state/types.pb.go#L37) type in the data base as the block results. This type has changed since v0.35 to contain the `FinalizeBlock` response. I'm wondering if we need to do any shimming to keep the old data retrieveable? * Similarly, this change is exposed via the RPC through [ResultBlockResults](https://github.com/tendermint/tendermint/blob/5721a13ab1f4479f9807f449f0bf5c536b9a05f2/rpc/coretypes/responses.go#L69) changing. Should we somehow shim or notify for this change? closes: #7658
2 years ago
  1. ---
  2. order: 1
  3. title: Basic concepts and definitions
  4. ---
  5. # Basic concepts and definitions
  6. ## Connections
  7. ABCI++ applications can run either within the _same_ process as the Tendermint
  8. state-machine replication engine, or as a _separate_ process from the state-machine
  9. replication engine. When run within the same process, Tendermint will call the ABCI++
  10. application methods directly as Go method calls.
  11. When Tendermint and the ABCI++ application are run as separate processes, Tendermint
  12. opens four connections to the application for ABCI++ methods. The connections each
  13. handle a subset of the ABCI++ method calls. These subsets are defined as follows:
  14. ### **Consensus** connection
  15. * Driven by a consensus protocol and is responsible for block execution.
  16. * Handles the `InitChain`, `PrepareProposal`, `ProcessProposal`, `ExtendVote`,
  17. `VerifyVoteExtension`, and `FinalizeBlock` method calls.
  18. ### **Mempool** connection
  19. * For validating new transactions, before they're shared or included in a block.
  20. * Handles the `CheckTx` calls.
  21. ### **Info** connection
  22. * For initialization and for queries from the user.
  23. * Handles the `Info` and `Query` calls.
  24. ### **Snapshot** connection
  25. * For serving and restoring [state sync snapshots](../abci/apps.md#state-sync).
  26. * Handles the `ListSnapshots`, `LoadSnapshotChunk`, `OfferSnapshot`, and `ApplySnapshotChunk` calls.
  27. Additionally, there is a `Flush` method that is called on every connection,
  28. and an `Echo` method that is just for debugging.
  29. >**TODO** Figure out what to do with this.
  30. More details on managing state across connections can be found in the section on
  31. [ABCI Applications](../abci/apps.md).
  32. ## Errors
  33. The `Query`, and `CheckTx` methods include a `Code` field in their `Response*`.
  34. The `Code` field is also included in type `TxResult`, used by
  35. method `FinalizeBlock`'s `Response*`.
  36. Field `Code` is meant to contain an application-specific response code.
  37. A response code of `0` indicates no error. Any other response code
  38. indicates to Tendermint that an error occurred.
  39. These methods also return a `Codespace` string to Tendermint. This field is
  40. used to disambiguate `Code` values returned by different domains of the
  41. Application. The `Codespace` is a namespace for the `Code`.
  42. Methods `Echo`, `Info`, and `InitChain` do not return errors.
  43. An error in any of these methods represents a critical issue that Tendermint
  44. has no reasonable way to handle. If there is an error in one
  45. of these methods, the Application must crash to ensure that the error is safely
  46. handled by an operator.
  47. Method `FinalizeBlock` is a special case. It contains a number of
  48. `Code` and `Codespace` fields as part of type `TxResult`. Each of
  49. these codes reports errors related to the transaction it is attached to.
  50. However, `FinalizeBlock` does not return errors at the top level, so the
  51. same considerations on critical issues made for `Echo`, `Info`, and
  52. `InitChain` also apply here.
  53. The handling of non-zero response codes by Tendermint is described below
  54. ### `CheckTx`
  55. The `CheckTx` ABCI++ method controls what transactions are considered for inclusion
  56. in a block.
  57. When Tendermint receives a `ResponseCheckTx` with a non-zero `Code`, the associated
  58. transaction will not be added to Tendermint's mempool or it will be removed if
  59. it is already included.
  60. ### `TxResult` (as part of `FinalizeBlock`)
  61. The `TxResult` type delivers transactions from Tendermint to the Application.
  62. When Tendermint receives a `ResponseFinalizeBlock` containing a `TxResult`
  63. with a non-zero `Code`, the response code is logged.
  64. The transaction was already included in a block, so the `Code` does not influence
  65. Tendermint consensus.
  66. ### `Query`
  67. The `Query` ABCI++ method queries the Application for information about application state.
  68. When Tendermint receives a `ResponseQuery` with a non-zero `Code`, this code is
  69. returned directly to the client that initiated the query.
  70. ## Events
  71. Method `CheckTx` includes an `Events` field in its `Response*`.
  72. Method `FinalizeBlock` includes an `Events` field at the top level in its
  73. `Response*`, and one `events` field per transaction included in the block.
  74. Applications may respond to these ABCI++ methods with a set of events.
  75. Events allow applications to associate metadata about ABCI++ method execution with the
  76. transactions and blocks this metadata relates to.
  77. Events returned via these ABCI++ methods do not impact Tendermint consensus in any way
  78. and instead exist to power subscriptions and queries of Tendermint state.
  79. An `Event` contains a `type` and a list of `EventAttributes`, which are key-value
  80. string pairs denoting metadata about what happened during the method's (or transaction's)
  81. execution. `Event` values can be used to index transactions and blocks according to what
  82. happened during their execution.
  83. Each event has a `type` which is meant to categorize the event for a particular
  84. `Response*` or `Tx`. A `Response*` or `Tx` may contain multiple events with duplicate
  85. `type` values, where each distinct entry is meant to categorize attributes for a
  86. particular event. Every key and value in an event's attributes must be UTF-8
  87. encoded strings along with the event type itself.
  88. ```protobuf
  89. message Event {
  90. string type = 1;
  91. repeated EventAttribute attributes = 2;
  92. }
  93. ```
  94. The attributes of an `Event` consist of a `key`, a `value`, and an `index` flag. The
  95. index flag notifies the Tendermint indexer to index the attribute. The value of
  96. the `index` flag is non-deterministic and may vary across different nodes in the network.
  97. ```protobuf
  98. message EventAttribute {
  99. bytes key = 1;
  100. bytes value = 2;
  101. bool index = 3; // nondeterministic
  102. }
  103. ```
  104. Example:
  105. ```go
  106. abci.ResponseCheckTx{
  107. // ...
  108. Events: []abci.Event{
  109. {
  110. Type: "validator.provisions",
  111. Attributes: []abci.EventAttribute{
  112. abci.EventAttribute{Key: []byte("address"), Value: []byte("..."), Index: true},
  113. abci.EventAttribute{Key: []byte("amount"), Value: []byte("..."), Index: true},
  114. abci.EventAttribute{Key: []byte("balance"), Value: []byte("..."), Index: true},
  115. },
  116. },
  117. {
  118. Type: "validator.provisions",
  119. Attributes: []abci.EventAttribute{
  120. abci.EventAttribute{Key: []byte("address"), Value: []byte("..."), Index: true},
  121. abci.EventAttribute{Key: []byte("amount"), Value: []byte("..."), Index: false},
  122. abci.EventAttribute{Key: []byte("balance"), Value: []byte("..."), Index: false},
  123. },
  124. },
  125. {
  126. Type: "validator.slashed",
  127. Attributes: []abci.EventAttribute{
  128. abci.EventAttribute{Key: []byte("address"), Value: []byte("..."), Index: false},
  129. abci.EventAttribute{Key: []byte("amount"), Value: []byte("..."), Index: true},
  130. abci.EventAttribute{Key: []byte("reason"), Value: []byte("..."), Index: true},
  131. },
  132. },
  133. // ...
  134. },
  135. }
  136. ```
  137. ## EvidenceType
  138. Tendermint's security model relies on the use of "evidence". Evidence is proof of
  139. malicious behaviour by a network participant. It is the responsibility of Tendermint
  140. to detect such malicious behaviour. When malicious behavior is detected, Tendermint
  141. will gossip evidence of the behavior to other nodes and commit the evidence to
  142. the chain once it is verified by all validators. This evidence will then be
  143. passed on to the Application through ABCI++. It is the responsibility of the
  144. Application to handle the evidence and exercise punishment.
  145. EvidenceType has the following protobuf format:
  146. ```protobuf
  147. enum EvidenceType {
  148. UNKNOWN = 0;
  149. DUPLICATE_VOTE = 1;
  150. LIGHT_CLIENT_ATTACK = 2;
  151. }
  152. ```
  153. There are two forms of evidence: Duplicate Vote and Light Client Attack. More
  154. information can be found in either [data structures](../core/data_structures.md)
  155. or [accountability](../light-client/accountability/)
  156. ## Vote Extensions
  157. According to the Tendermint algorithm, a proposed block needs at least a predefined
  158. number of precommit votes in order to be decided. Tendermint gathers all the valid
  159. precommit votes for the decided block that it receives before the block is decided,
  160. and then includes these votes in the proposed block for the next height whenever
  161. the local process is the proposer of the round.
  162. When Tendermint's consensus is about to send a non-`nil` precommit message, it calls
  163. method `ExtendVote`, which gives the Application the opportunity to include
  164. non-deterministic data, opaque to Tendermint, that will be attached to the precommit
  165. message. The data, called _vote extension_, will also be made available to the
  166. application in the next height, along with the vote it is extending, in the rounds
  167. where the local process is the proposer.
  168. The vote extension data is split into two parts, one signed by Tendermint as part
  169. of the vote data structure, and the other (optionally) signed by the Application.
  170. The Application may also choose not to include any vote extension.
  171. When another process receives a precommit message with a vote extension, it calls
  172. method `VerifyVoteExtension` so that the Application can validate the data received.
  173. If the validation fails, the precommit message will be deemed invalid and ignored
  174. by Tendermint. This has negative impact on Tendermint's liveness, i.e., if repeatedly vote extensions by correct validators cannot be verified by correct validators, Tendermint may not be able to finalize a block even if sufficiently many (+2/3) of the validators send precommit votes for that block. Thus, `VerifyVoteExtension` should only be used with special care.
  175. As a general rule, an Application that detects an invalid vote extension SHOULD
  176. accept it in `ResponseVerifyVoteExtension` and ignore it in its own logic.
  177. ## Determinism
  178. ABCI++ applications must implement deterministic finite-state machines to be
  179. securely replicated by the Tendermint consensus engine. This means block execution
  180. over the Consensus Connection must be strictly deterministic: given the same
  181. ordered set of requests, all nodes will compute identical responses, for all
  182. successive `FinalizeBlock` calls. This is critical, because the
  183. responses are included in the header of the next block, either via a Merkle root
  184. or directly, so all nodes must agree on exactly what they are.
  185. For this reason, it is recommended that applications not be exposed to any
  186. external user or process except via the ABCI connections to a consensus engine
  187. like Tendermint Core. The Application must only change its state based on input
  188. from block execution (`FinalizeBlock` calls), and not through
  189. any other kind of request. This is the only way to ensure all nodes see the same
  190. transactions and compute the same results.
  191. Some Applications may choose to execute the blocks that are about to be proposed
  192. (via `PrepareProposal`), or those that the Application is asked to validate
  193. (via `Processproposal`). However the state changes caused by processing those
  194. proposed blocks must never replace the previous state until `FinalizeBlock` confirms
  195. the block decided.
  196. Additionally, vote extensions or the validation thereof (via `ExtendVote` or
  197. `VerifyVoteExtension`) must _never_ have side effects on the current state.
  198. They can only be used when their data is included in a block.
  199. If there is some non-determinism in the state machine, consensus will eventually
  200. fail as nodes disagree over the correct values for the block header. The
  201. non-determinism must be fixed and the nodes restarted.
  202. Sources of non-determinism in applications may include:
  203. * Hardware failures
  204. * Cosmic rays, overheating, etc.
  205. * Node-dependent state
  206. * Random numbers
  207. * Time
  208. * Underspecification
  209. * Library version changes
  210. * Race conditions
  211. * Floating point numbers
  212. * JSON or protobuf serialization
  213. * Iterating through hash-tables/maps/dictionaries
  214. * External Sources
  215. * Filesystem
  216. * Network calls (eg. some external REST API service)
  217. See [#56](https://github.com/tendermint/abci/issues/56) for original discussion.
  218. Note that some methods (`Query, CheckTx, FinalizeBlock`) return
  219. explicitly non-deterministic data in the form of `Info` and `Log` fields. The `Log` is
  220. intended for the literal output from the Application's logger, while the
  221. `Info` is any additional info that should be returned. These are the only fields
  222. that are not included in block header computations, so we don't need agreement
  223. on them. All other fields in the `Response*` must be strictly deterministic.
  224. ## Block Execution
  225. The first time a new blockchain is started, Tendermint calls
  226. `InitChain`. From then on, method `FinalizeBlock` is executed at the end of each
  227. block, resulting in an updated Application state.
  228. During consensus execution of a block height, before method `FinalizeBlock` is
  229. called, methods `PrepareProposal`, `ProcessProposal`, `ExtendVote`, and
  230. `VerifyVoteExtension` may be called a number of times.
  231. See [Tendermint's expected behavior](abci++_tmint_expected_behavior_002_draft.md)
  232. for details on the possible call sequences of these methods.
  233. Method `PrepareProposal` is called every time Tendermint is about to send
  234. a proposal message, but no previous proposal has been locked at Tendermint level.
  235. Tendermint gathers outstanding transactions from the mempool
  236. (see [PrepareProposal](#PrepareProposal)), generates a block header and uses
  237. them to create a block to propose. Then, it calls `RequestPrepareProposal`
  238. with the newly created proposal, called _raw proposal_. The Application can
  239. make changes to the raw proposal, such as modifying transactions, and returns
  240. the (potentially) modified proposal, called _prepared proposal_ in the
  241. `Response*` call. The logic modifying the raw proposal can be non-deterministic.
  242. When Tendermint receives a prepared proposal it uses method `ProcessProposal`
  243. to inform the Application of the proposal just received. The Application cannot
  244. modify the proposal at this point but can reject it if it realises it is invalid.
  245. If that is the case, Tendermint will prevote `nil` on the proposal, which has
  246. strong liveness implications for Tendermint. As a general rule, the Application
  247. SHOULD accept a prepared proposal passed via `ProcessProposal`, even if a part of
  248. the proposal is invalid (e.g., an invalid transaction); the Application can later
  249. ignore the invalid part of the prepared proposal at block execution time.
  250. Cryptographic commitments to the block and transaction results, via the corresponding
  251. parameters in `FinalizeBlockResponse` are included in the header of the next block.
  252. ## Next-block execution and same-block execution
  253. With ABCI++ predecessor, ABCI, the only moment when the Application had access to a
  254. block was when it was decided. This led to a block execution model, called _next-block
  255. execution_, where some fields hashed in a block header refer to the execution of the
  256. previous block, namely:
  257. * the merkle root of the Application's state
  258. * the transaction results
  259. * the consensus parameter updates
  260. * the validator updates
  261. With ABCI++, an Application may decide to keep using the next-block execution model;
  262. however the new methods introduced, `PrepareProposal` and `ProcessProposal` allow
  263. for a new execution model, called _same-block execution_. An Application implementing
  264. this execution model, upon receiving a raw proposal via `RequestPrepareProposal`
  265. and potentially modifying its transaction list,
  266. fully executes the resulting prepared proposal as though it was the decided block.
  267. The results of the block execution are used as follows:
  268. * the Application keeps the events generated and provides them if `FinalizeBlock`
  269. is finally called on this prepared proposal.
  270. * the merkle root resulting from executing the prepared proposal is provided in
  271. `ResponsePrepareProposal` and thus refers to the **current block**. Tendermint
  272. will use it in the prepared proposal's header.
  273. * likewise, the transaction results from executing the prepared proposal are
  274. provided in `ResponsePrepareProposal` and refer to the transactions in the
  275. **current block**. Tendermint will use them to calculate the results hash
  276. in the prepared proposal's header.
  277. * the consensus parameter updates and validator updates are also provided in
  278. `ResponsePrepareProposal` and reflect the result of the prepared proposal's
  279. execution. They come into force in height H+1 (as opposed to the H+2 rule
  280. in next-block execution model).
  281. If the Application decides to keep the next-block execution model, it will not
  282. provide any data in `ResponsePrepareProposal`, other than an optionally modified
  283. transaction list.
  284. In the long term, the execution model will be set in a new boolean parameter
  285. *same_block* in `ConsensusParams`.
  286. It should **not** be changed once the blockchain has started, unless the Application
  287. developers _really_ know what they are doing.
  288. However, modifying `ConsensusParams` structure cannot be done lightly if we are to
  289. preserve blockchain compatibility. Therefore we need an interim solution until
  290. soft upgrades are specified and implemented in Tendermint. This somewhat _unsafe_
  291. solution consists in Tendermint assuming same-block execution if the Application
  292. fills the above mentioned fields in `ResponsePrepareProposal`.
  293. ## Tendermint timeouts in same-block execution
  294. The new same-block execution mode requires the Application to fully execute the
  295. prepared block at `PrepareProposal` time. This execution is synchronous, so
  296. Tendermint cannot make progress until the Application returns from `PrepareProposal`.
  297. This stands on Tendermint's critical path: if the Application takes a long time
  298. executing the block, the default value of _TimeoutPropose_ might not be sufficient
  299. to accomodate the long block execution time and non-proposer processes might time
  300. out and prevote `nil`, thus starting a further round unnecessarily.
  301. The Application is the best suited to provide a value for _TimeoutPropose_ so
  302. that the block execution time upon `PrepareProposal` fits well in the propose
  303. timeout interval.
  304. Currently, the Application can override the value of _TimeoutPropose_ via the
  305. `config.toml` file. In the future, `ConsensusParams` may have an extra field
  306. with the current _TimeoutPropose_ value so that the Application has the possibility
  307. to adapt it at every height.
  308. ## State Sync
  309. State sync allows new nodes to rapidly bootstrap by discovering, fetching, and applying
  310. state machine snapshots instead of replaying historical blocks. For more details, see the
  311. [state sync section](../p2p/messages/state-sync.md).
  312. New nodes will discover and request snapshots from other nodes in the P2P network.
  313. A Tendermint node that receives a request for snapshots from a peer will call
  314. `ListSnapshots` on its Application to retrieve any local state snapshots. After receiving
  315. snapshots from peers, the new node will offer each snapshot received from a peer
  316. to its local Application via the `OfferSnapshot` method.
  317. Snapshots may be quite large and are thus broken into smaller "chunks" that can be
  318. assembled into the whole snapshot. Once the Application accepts a snapshot and
  319. begins restoring it, Tendermint will fetch snapshot "chunks" from existing nodes.
  320. The node providing "chunks" will fetch them from its local Application using
  321. the `LoadSnapshotChunk` method.
  322. As the new node receives "chunks" it will apply them sequentially to the local
  323. application with `ApplySnapshotChunk`. When all chunks have been applied, the
  324. Application's `AppHash` is retrieved via an `Info` query. The `AppHash` is then
  325. compared to the blockchain's `AppHash` which is verified via
  326. [light client verification](../light-client/verification/README.md).