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.

453 lines
18 KiB

  1. # Applications
  2. Please ensure you've first read the spec for [ABCI Methods and Types](abci.md)
  3. Here we cover the following components of ABCI applications:
  4. - [Connection State](#state) - the interplay between ABCI connections and application state
  5. and the differences between `CheckTx` and `DeliverTx`.
  6. - [Transaction Results](#transaction-results) - rules around transaction
  7. results and validity
  8. - [Validator Set Updates](#validator-updates) - how validator sets are
  9. changed during `InitChain` and `EndBlock`
  10. - [Query](#query) - standards for using the `Query` method and proofs about the
  11. application state
  12. - [Crash Recovery](#crash-recovery) - handshake protocol to synchronize
  13. Tendermint and the application on startup.
  14. ## State
  15. Since Tendermint maintains three concurrent ABCI connections, it is typical
  16. for an application to maintain a distinct state for each, and for the states to
  17. be synchronized during `Commit`.
  18. ### Commit
  19. Application state should only be persisted to disk during `Commit`.
  20. Before `Commit` is called, Tendermint locks and flushes the mempool so that no new messages will
  21. be received on the mempool connection. This provides an opportunity to safely update all three
  22. states to the latest committed state at once.
  23. When `Commit` completes, it unlocks the mempool.
  24. WARNING: if the ABCI app logic processing the `Commit` message sends a
  25. `/broadcast_tx_sync` or `/broadcast_tx_commit` and waits for the response
  26. before proceeding, it will deadlock. Executing those `broadcast_tx` calls
  27. involves acquiring a lock that is held during the `Commit` call, so it's not
  28. possible. If you make the call to the `broadcast_tx` endpoints concurrently,
  29. that's no problem, it just can't be part of the sequential logic of the
  30. `Commit` function.
  31. ### Consensus Connection
  32. The Consensus Connection should maintain a `DeliverTxState` -
  33. the working state for block execution. It should be updated by the calls to
  34. `BeginBlock`, `DeliverTx`, and `EndBlock` during block execution and committed to
  35. disk as the "latest committed state" during `Commit`.
  36. Updates made to the DeliverTxState by each method call must be readable by each subsequent method -
  37. ie. the updates are linearizable.
  38. ### Mempool Connection
  39. The Mempool Connection should maintain a `CheckTxState`
  40. to sequentially process pending transactions in the mempool that have
  41. not yet been committed. It should be initialized to the latest committed state
  42. at the end of every `Commit`.
  43. The CheckTxState may be updated concurrently with the DeliverTxState, as
  44. messages may be sent concurrently on the Consensus and Mempool connections. However,
  45. before calling `Commit`, Tendermint will lock and flush the mempool connection,
  46. ensuring that all existing CheckTx are responded to and no new ones can
  47. begin.
  48. After `Commit`, CheckTx is run again on all transactions that remain in the
  49. node's local mempool after filtering those included in the block. To prevent the
  50. mempool from rechecking all transactions every time a block is committed, set
  51. the configuration option `mempool.recheck=false`. As of Tendermint v0.32.1,
  52. an additional `Type` parameter is made available to the CheckTx function that
  53. indicates whether an incoming transaction is new (`CheckTxType_New`), or a
  54. recheck (`CheckTxType_Recheck`).
  55. Finally, the mempool will unlock and new transactions can be processed through CheckTx again.
  56. Note that CheckTx doesn't have to check everything that affects transaction validity; the
  57. expensive things can be skipped. In fact, CheckTx doesn't have to check
  58. anything; it might say that any transaction is a valid transaction.
  59. Unlike DeliverTx, CheckTx is just there as
  60. a sort of weak filter to keep invalid transactions out of the blockchain. It's
  61. weak, because a Byzantine node doesn't care about CheckTx; it can propose a
  62. block full of invalid transactions if it wants.
  63. ### Info Connection
  64. The Info Connection should maintain a `QueryState` for answering queries from the user,
  65. and for initialization when Tendermint first starts up (both described further
  66. below).
  67. It should always contain the latest committed state associated with the
  68. latest committed block.
  69. QueryState should be set to the latest `DeliverTxState` at the end of every `Commit`,
  70. ie. after the full block has been processed and the state committed to disk.
  71. Otherwise it should never be modified.
  72. ## Transaction Results
  73. `ResponseCheckTx` and `ResponseDeliverTx` contain the same fields.
  74. The `Info` and `Log` fields are non-deterministic values for debugging/convenience purposes
  75. that are otherwise ignored.
  76. The `Data` field must be strictly deterministic, but can be arbitrary data.
  77. ### Gas
  78. Ethereum introduced the notion of `gas` as an abstract representation of the
  79. cost of resources used by nodes when processing transactions. Every operation in the
  80. Ethereum Virtual Machine uses some amount of gas, and gas can be accepted at a market-variable price.
  81. Users propose a maximum amount of gas for their transaction; if the tx uses less, they get
  82. the difference credited back. Tendermint adopts a similar abstraction,
  83. though uses it only optionally and weakly, allowing applications to define
  84. their own sense of the cost of execution.
  85. In Tendermint, the `ConsensusParams.Block.MaxGas` limits the amount of `gas` that can be used in a block.
  86. The default value is `-1`, meaning no limit, or that the concept of gas is
  87. meaningless.
  88. Responses contain a `GasWanted` and `GasUsed` field. The former is the maximum
  89. amount of gas the sender of a tx is willing to use, and the later is how much it actually
  90. used. Applications should enforce that `GasUsed <= GasWanted` - ie. tx execution
  91. should halt before it can use more resources than it requested.
  92. When `MaxGas > -1`, Tendermint enforces the following rules:
  93. - `GasWanted <= MaxGas` for all txs in the mempool
  94. - `(sum of GasWanted in a block) <= MaxGas` when proposing a block
  95. If `MaxGas == -1`, no rules about gas are enforced.
  96. Note that Tendermint does not currently enforce anything about Gas in the consensus, only the mempool.
  97. This means it does not guarantee that committed blocks satisfy these rules!
  98. It is the application's responsibility to return non-zero response codes when gas limits are exceeded.
  99. The `GasUsed` field is ignored completely by Tendermint. That said, applications should enforce:
  100. - `GasUsed <= GasWanted` for any given transaction
  101. - `(sum of GasUsed in a block) <= MaxGas` for every block
  102. In the future, we intend to add a `Priority` field to the responses that can be
  103. used to explicitly prioritize txs in the mempool for inclusion in a block
  104. proposal. See [#1861](https://github.com/tendermint/tendermint/issues/1861).
  105. ### CheckTx
  106. If `Code != 0`, it will be rejected from the mempool and hence
  107. not broadcasted to other peers and not included in a proposal block.
  108. `Data` contains the result of the CheckTx transaction execution, if any. It is
  109. semantically meaningless to Tendermint.
  110. `Tags` include any tags for the execution, though since the transaction has not
  111. been committed yet, they are effectively ignored by Tendermint.
  112. ### DeliverTx
  113. If DeliverTx returns `Code != 0`, the transaction will be considered invalid,
  114. though it is still included in the block.
  115. `Data` contains the result of the CheckTx transaction execution, if any. It is
  116. semantically meaningless to Tendermint.
  117. Both the `Code` and `Data` are included in a structure that is hashed into the
  118. `LastResultsHash` of the next block header.
  119. `Tags` include any tags for the execution, which Tendermint will use to index
  120. the transaction by. This allows transactions to be queried according to what
  121. events took place during their execution.
  122. See issue [#1007](https://github.com/tendermint/tendermint/issues/1007) for how
  123. the tags will be hashed into the next block header.
  124. ## Validator Updates
  125. The application may set the validator set during InitChain, and update it during
  126. EndBlock.
  127. Note that the maximum total power of the validator set is bounded by
  128. `MaxTotalVotingPower = MaxInt64 / 8`. Applications are responsible for ensuring
  129. they do not make changes to the validator set that cause it to exceed this
  130. limit.
  131. Additionally, applications must ensure that a single set of updates does not contain any duplicates -
  132. a given public key can only appear in an update once. If an update includes
  133. duplicates, the block execution will fail irrecoverably.
  134. ### InitChain
  135. ResponseInitChain can return a list of validators.
  136. If the list is empty, Tendermint will use the validators loaded in the genesis
  137. file.
  138. If the list is not empty, Tendermint will use it for the validator set.
  139. This way the application can determine the initial validator set for the
  140. blockchain.
  141. ### EndBlock
  142. Updates to the Tendermint validator set can be made by returning
  143. `ValidatorUpdate` objects in the `ResponseEndBlock`:
  144. ```
  145. message ValidatorUpdate {
  146. PubKey pub_key
  147. int64 power
  148. }
  149. message PubKey {
  150. string type
  151. bytes data
  152. }
  153. ```
  154. The `pub_key` currently supports only one type:
  155. - `type = "ed25519"` and `data = <raw 32-byte public key>`
  156. The `power` is the new voting power for the validator, with the
  157. following rules:
  158. - power must be non-negative
  159. - if power is 0, the validator must already exist, and will be removed from the
  160. validator set
  161. - if power is non-0:
  162. - if the validator does not already exist, it will be added to the validator
  163. set with the given power
  164. - if the validator does already exist, its power will be adjusted to the given power
  165. - the total power of the new validator set must not exceed MaxTotalVotingPower
  166. Note the updates returned in block `H` will only take effect at block `H+2`.
  167. ## Consensus Parameters
  168. ConsensusParams enforce certain limits in the blockchain, like the maximum size
  169. of blocks, amount of gas used in a block, and the maximum acceptable age of
  170. evidence. They can be set in InitChain and updated in EndBlock.
  171. ### Block.MaxBytes
  172. The maximum size of a complete Amino encoded block.
  173. This is enforced by Tendermint consensus.
  174. This implies a maximum tx size that is this MaxBytes, less the expected size of
  175. the header, the validator set, and any included evidence in the block.
  176. Must have `0 < MaxBytes < 100 MB`.
  177. ### Block.MaxGas
  178. The maximum of the sum of `GasWanted` in a proposed block.
  179. This is *not* enforced by Tendermint consensus.
  180. It is left to the app to enforce (ie. if txs are included past the
  181. limit, they should return non-zero codes). It is used by Tendermint to limit the
  182. txs included in a proposed block.
  183. Must have `MaxGas >= -1`.
  184. If `MaxGas == -1`, no limit is enforced.
  185. ### Block.TimeIotaMs
  186. The minimum time between consecutive blocks (in milliseconds).
  187. This is enforced by Tendermint consensus.
  188. Must have `TimeIotaMs > 0` to ensure time monotonicity.
  189. ### EvidenceParams.MaxAge
  190. This is the maximum age of evidence.
  191. This is enforced by Tendermint consensus.
  192. If a block includes evidence older than this, the block will be rejected
  193. (validators won't vote for it).
  194. Must have `MaxAge > 0`.
  195. ### Updates
  196. The application may set the ConsensusParams during InitChain, and update them during
  197. EndBlock. If the ConsensusParams is empty, it will be ignored. Each field
  198. that is not empty will be applied in full. For instance, if updating the
  199. Block.MaxBytes, applications must also set the other Block fields (like
  200. Block.MaxGas), even if they are unchanged, as they will otherwise cause the
  201. value to be updated to 0.
  202. #### InitChain
  203. ResponseInitChain includes a ConsensusParams.
  204. If its nil, Tendermint will use the params loaded in the genesis
  205. file. If it's not nil, Tendermint will use it.
  206. This way the application can determine the initial consensus params for the
  207. blockchain.
  208. #### EndBlock
  209. ResponseEndBlock includes a ConsensusParams.
  210. If its nil, Tendermint will do nothing.
  211. If it's not nil, Tendermint will use it.
  212. This way the application can update the consensus params over time.
  213. Note the updates returned in block `H` will take effect right away for block
  214. `H+1`.
  215. ## Query
  216. Query is a generic method with lots of flexibility to enable diverse sets
  217. of queries on application state. Tendermint makes use of Query to filter new peers
  218. based on ID and IP, and exposes Query to the user over RPC.
  219. Note that calls to Query are not replicated across nodes, but rather query the
  220. local node's state - hence they may return stale reads. For reads that require
  221. consensus, use a transaction.
  222. The most important use of Query is to return Merkle proofs of the application state at some height
  223. that can be used for efficient application-specific lite-clients.
  224. Note Tendermint has technically no requirements from the Query
  225. message for normal operation - that is, the ABCI app developer need not implement
  226. Query functionality if they do not wish too.
  227. ### Query Proofs
  228. The Tendermint block header includes a number of hashes, each providing an
  229. anchor for some type of proof about the blockchain. The `ValidatorsHash` enables
  230. quick verification of the validator set, the `DataHash` gives quick
  231. verification of the transactions included in the block, etc.
  232. The `AppHash` is unique in that it is application specific, and allows for
  233. application-specific Merkle proofs about the state of the application.
  234. While some applications keep all relevant state in the transactions themselves
  235. (like Bitcoin and its UTXOs), others maintain a separated state that is
  236. computed deterministically *from* transactions, but is not contained directly in
  237. the transactions themselves (like Ethereum contracts and accounts).
  238. For such applications, the `AppHash` provides a much more efficient way to verify lite-client proofs.
  239. ABCI applications can take advantage of more efficient lite-client proofs for
  240. their state as follows:
  241. - return the Merkle root of the deterministic application state in
  242. `ResponseCommit.Data`.
  243. - it will be included as the `AppHash` in the next block.
  244. - return efficient Merkle proofs about that application state in `ResponseQuery.Proof`
  245. that can be verified using the `AppHash` of the corresponding block.
  246. For instance, this allows an application's lite-client to verify proofs of
  247. absence in the application state, something which is much less efficient to do using the block hash.
  248. Some applications (eg. Ethereum, Cosmos-SDK) have multiple "levels" of Merkle trees,
  249. where the leaves of one tree are the root hashes of others. To support this, and
  250. the general variability in Merkle proofs, the `ResponseQuery.Proof` has some minimal structure:
  251. ```
  252. message Proof {
  253. repeated ProofOp ops
  254. }
  255. message ProofOp {
  256. string type = 1;
  257. bytes key = 2;
  258. bytes data = 3;
  259. }
  260. ```
  261. Each `ProofOp` contains a proof for a single key in a single Merkle tree, of the specified `type`.
  262. This allows ABCI to support many different kinds of Merkle trees, encoding
  263. formats, and proofs (eg. of presence and absence) just by varying the `type`.
  264. The `data` contains the actual encoded proof, encoded according to the `type`.
  265. When verifying the full proof, the root hash for one ProofOp is the value being
  266. verified for the next ProofOp in the list. The root hash of the final ProofOp in
  267. the list should match the `AppHash` being verified against.
  268. ### Peer Filtering
  269. When Tendermint connects to a peer, it sends two queries to the ABCI application
  270. using the following paths, with no additional data:
  271. - `/p2p/filter/addr/<IP:PORT>`, where `<IP:PORT>` denote the IP address and
  272. the port of the connection
  273. - `p2p/filter/id/<ID>`, where `<ID>` is the peer node ID (ie. the
  274. pubkey.Address() for the peer's PubKey)
  275. If either of these queries return a non-zero ABCI code, Tendermint will refuse
  276. to connect to the peer.
  277. ### Paths
  278. Queries are directed at paths, and may optionally include additional data.
  279. The expectation is for there to be some number of high level paths
  280. differentiating concerns, like `/p2p`, `/store`, and `/app`. Currently,
  281. Tendermint only uses `/p2p`, for filtering peers. For more advanced use, see the
  282. implementation of
  283. [Query in the Cosmos-SDK](https://github.com/cosmos/cosmos-sdk/blob/v0.23.1/baseapp/baseapp.go#L333).
  284. ## Crash Recovery
  285. On startup, Tendermint calls the `Info` method on the Info Connection to get the latest
  286. committed state of the app. The app MUST return information consistent with the
  287. last block it succesfully completed Commit for.
  288. If the app succesfully committed block H but not H+1, then `last_block_height = H` and `last_block_app_hash = <hash returned by Commit for block H>`. If the app
  289. failed during the Commit of block H, then `last_block_height = H-1` and
  290. `last_block_app_hash = <hash returned by Commit for block H-1, which is the hash in the header of block H>`.
  291. We now distinguish three heights, and describe how Tendermint syncs itself with
  292. the app.
  293. ```
  294. storeBlockHeight = height of the last block Tendermint saw a commit for
  295. stateBlockHeight = height of the last block for which Tendermint completed all
  296. block processing and saved all ABCI results to disk
  297. appBlockHeight = height of the last block for which ABCI app succesfully
  298. completed Commit
  299. ```
  300. Note we always have `storeBlockHeight >= stateBlockHeight` and `storeBlockHeight >= appBlockHeight`
  301. Note also we never call Commit on an ABCI app twice for the same height.
  302. The procedure is as follows.
  303. First, some simple start conditions:
  304. If `appBlockHeight == 0`, then call InitChain.
  305. If `storeBlockHeight == 0`, we're done.
  306. Now, some sanity checks:
  307. If `storeBlockHeight < appBlockHeight`, error
  308. If `storeBlockHeight < stateBlockHeight`, panic
  309. If `storeBlockHeight > stateBlockHeight+1`, panic
  310. Now, the meat:
  311. If `storeBlockHeight == stateBlockHeight && appBlockHeight < storeBlockHeight`,
  312. replay all blocks in full from `appBlockHeight` to `storeBlockHeight`.
  313. This happens if we completed processing the block, but the app forgot its height.
  314. If `storeBlockHeight == stateBlockHeight && appBlockHeight == storeBlockHeight`, we're done.
  315. This happens if we crashed at an opportune spot.
  316. If `storeBlockHeight == stateBlockHeight+1`
  317. This happens if we started processing the block but didn't finish.
  318. If `appBlockHeight < stateBlockHeight`
  319. replay all blocks in full from `appBlockHeight` to `storeBlockHeight-1`,
  320. and replay the block at `storeBlockHeight` using the WAL.
  321. This happens if the app forgot the last block it committed.
  322. If `appBlockHeight == stateBlockHeight`,
  323. replay the last block (storeBlockHeight) in full.
  324. This happens if we crashed before the app finished Commit
  325. If `appBlockHeight == storeBlockHeight`
  326. update the state using the saved ABCI responses but dont run the block against the real app.
  327. This happens if we crashed after the app finished Commit but before Tendermint saved the state.