github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/spec/abci/abci++_basic_concepts.md (about) 1 --- 2 order: 1 3 title: Overview and basic concepts 4 --- 5 6 ## Outline 7 8 - [Overview and basic concepts](#overview-and-basic-concepts) 9 - [ABCI++ vs. ABCI](#abci-vs-abci) 10 - [Method overview](#method-overview) 11 - [Consensus/block execution methods](#consensusblock-execution-methods) 12 - [Mempool methods](#mempool-methods) 13 - [Info methods](#info-methods) 14 - [State-sync methods](#state-sync-methods) 15 - [Other methods](#other-methods) 16 - [Proposal timeout](#proposal-timeout) 17 - [Deterministic State-Machine Replication](#deterministic-state-machine-replication) 18 - [Events](#events) 19 - [Evidence](#evidence) 20 - [Errors](#errors) 21 - [`CheckTx`](#checktx) 22 - [`DeliverTx`](#delivertx) 23 - [`Query`](#query) 24 25 # Overview and basic concepts 26 27 ## ABCI 2.0 vs. ABCI 28 29 [↑ Back to Outline](#outline) 30 31 The Application's main role is to execute blocks decided (a.k.a. finalized) by consensus. The 32 decided blocks are the consensus's main ouput to the (replicated) Application. With ABCI, the 33 application only interacts with consensus at *decision* time. This restricted mode of interaction 34 prevents numerous features for the Application, including many scalability improvements that are 35 now better understood than when ABCI was first written. For example, many ideas proposed to improve 36 scalability can be boiled down to "make the block proposers do work, so the network does not have 37 to". This includes optimizations such as transaction level signature aggregation, state transition 38 proofs, etc. Furthermore, many new security properties cannot be achieved in the current paradigm, 39 as the Application cannot require validators to do more than executing the transactions contained in 40 finalized blocks. This includes features such as threshold cryptography, and guaranteed IBC 41 connection attempts. 42 43 ABCI 2.0 addresses these limitations by allowing the application to intervene at two key places of 44 consensus execution: (a) at the moment a new proposal is to be created and (b) at the moment a 45 proposal is to be validated. The new interface allows block proposers to perform application-dependent 46 work in a block through the `PrepareProposal` method (a); and validators to perform application-dependent work 47 and checks in a proposed block through the `ProcessProposal` method (b). 48 49 <!-- Furthermore, ABCI++ coalesces {`BeginBlock`, [`DeliverTx`], `EndBlock`} into `FinalizeBlock`, as a 50 simplified, efficient way to deliver a decided block to the Application. --> 51 52 We plan to extend this to allow applications to intervene at the moment a (precommit) vote is sent/received. 53 The applications could then require their validators to do more than just validating blocks through the `ExtendVote` 54 and `VerifyVoteExtension` methods. 55 56 ## Methods overview 57 58 59 [↑ Back to Outline](#outline) 60 61 Methods can be classified into four categories: *consensus*, *mempool*, *info*, and *state-sync*. 62 63 ### Consensus/block execution methods 64 65 The first time a new blockchain is started, CometBFT calls `InitChain`. From then on, methods `BeginBlock`, 66 `DeliverTx` and `EndBlock` are executed upon the decision of each block, resulting in an updated Application 67 state. One `DeliverTx` is called for each transaction in the block. The result is an updated application state. 68 Cryptographic commitments to the results of `DeliverTx`, and an application-provided hash in `Commit` are included in the header of the next block. During the execution of an instance of consensus, which decides the block for a given 69 height, and before method `BeginBlock` is called, methods `PrepareProposal` and `ProcessProposal`, 70 may be called several times. See 71 [CometBFT's expected behavior](./abci++_comet_expected_behavior.md) for details on the possible 72 call sequences of these methods. 73 74 - [**InitChain:**](./abci++_methods.md#initchain) This method initializes the blockchain. 75 CometBFT calls it once upon genesis. 76 77 - [**PrepareProposal:**](./abci++_methods.md#prepareproposal) It allows the block 78 proposer to perform application-dependent work in a block before proposing it. 79 This enables, for instance, batch optimizations to a block, which has been empirically 80 demonstrated to be a key component for improved performance. Method `PrepareProposal` is called 81 every time CometBFT is about to broadcast a Proposal message and _validValue_ is `nil`. 82 CometBFT gathers outstanding transactions from the 83 mempool, generates a block header, and uses them to create a block to propose. Then, it calls 84 `RequestPrepareProposal` with the newly created proposal, called *raw proposal*. The Application 85 can make changes to the raw proposal, such as modifying the set of transactions or the order 86 in which they appear, and returns the 87 (potentially) modified proposal, called *prepared proposal* in the `ResponsePrepareProposal` 88 call. 89 The logic modifying the raw proposal MAY be non-deterministic. 90 91 - [**ProcessProposal:**](./abci++_methods.md#processproposal) It allows a validator to 92 perform application-dependent work in a proposed block. This enables features such as immediate 93 block execution, and allows the Application to reject invalid blocks. 94 95 CometBFT calls it when it receives a proposal and _validValue_ is `nil`. 96 The Application cannot modify the proposal at this point but can reject it if 97 invalid. If that is the case, the consensus algorithm will prevote `nil` on the proposal, which has 98 strong liveness implications for CometBFT. As a general rule, the Application 99 SHOULD accept a prepared proposal passed via `ProcessProposal`, even if a part of 100 the proposal is invalid (e.g., an invalid transaction); the Application can 101 ignore the invalid part of the prepared proposal at block execution time. 102 The logic in `ProcessProposal` MUST be deterministic. 103 104 - [**BeginBlock:**](./abci++_methods.md#beginblock) Is called exactly once after a block has been decided 105 and executes once before all `DeliverTx` method calls. 106 107 - [**DeliverTx**](./abci++_methods.md#delivertx) Upon completion of `BeginBlock`, 108 `DeliverTx` is called once 109 for each of the transactions within the block. The application defines further checks to confirm their 110 validity - for example a key-value store might verify that the key does not already exist. Note that 111 even if a transaction does not pass the check in `DeliverTx`, it will still be part of the block as the 112 block has already been voted on (unlike with `CheckTx` which would dismiss such a transaction). The responses 113 returned by `DeliverTx` are included in the header of the next block. 114 115 - [**EndBlock**](./abci++_methods.md#endblock) It is executed once all transactions have been processed via 116 `DeliverTx` to inform the application that no other transactions will be delivered as part of the current 117 block and to ask for changes of the validator set and consensus parameters to be used in the following block. 118 As with `DeliverTx`, cryptographic commitments of the responses returned are included in the header of the next block. 119 <!-- 120 121 - [**ExtendVote:**](./abci++_methods.md#extendvote) It allows applications to force their 122 validators to do more than just validate within consensus. `ExtendVote` allows applications to 123 include non-deterministic data, opaque to the consensus algorithm, to precommit messages (the final round of 124 voting). The data, called *vote extension*, will be broadcast and received together with the 125 vote it is extending, and will be made available to the Application in the next height, 126 in the rounds where the local process is the proposer. 127 CometBFT calls `ExtendVote` when the consensus algorithm is about to send a non-`nil` precommit message. 128 If the Application does not have vote extension information to provide at that time, it returns 129 a 0-length byte array as its vote extension. 130 The logic in `ExtendVote` MAY be non-deterministic. 131 132 - [**VerifyVoteExtension:**](./abci++_methods.md#verifyvoteextension) It allows 133 validators to validate the vote extension data attached to a precommit message. If the validation 134 fails, the whole precommit message will be deemed invalid and ignored by consensus algorithm. 135 This has a negative impact on liveness, i.e., if vote extensions repeatedly cannot be 136 verified by correct validators, the consensus algorithm may not be able to finalize a block even if sufficiently 137 many (+2/3) validators send precommit votes for that block. Thus, `VerifyVoteExtension` 138 should be used with special care. 139 As a general rule, an Application that detects an invalid vote extension SHOULD 140 accept it in `ResponseVerifyVoteExtension` and ignore it in its own logic. CometBFT calls it when 141 a process receives a precommit message with a (possibly empty) vote extension. 142 --> 143 144 <!--- 145 - [**FinalizeBlock:**](./abci++_methods.md#finalizeblock) It delivers a decided block to the 146 Application. The Application must execute the transactions in the block deterministically and 147 update its state accordingly. Cryptographic commitments to the block and transaction results, 148 returned via the corresponding parameters in `ResponseFinalizeBlock`, are included in the header 149 of the next block. CometBFT calls it when a new block is decided. 150 --> 151 - [**Commit:**](./abci++_methods.md#commit) Instructs the Application to persist its 152 state. It is a fundamental part of CometBFT's crash-recovery mechanism that ensures the 153 synchronization between CometBFT and the Applicatin upon recovery. CometBFT calls it just after 154 having persisted the data returned by calls to `DeliverTx` and `EndBlock` . The Application can now discard 155 any state or data except the one resulting from executing the transactions in the decided block. 156 157 ### Mempool methods 158 159 - [**CheckTx:**](./abci++_methods.md#checktx) This method allows the Application to validate 160 transactions. Validation can be stateless (e.g., checking signatures ) or stateful 161 (e.g., account balances). The type of validation performed is up to the application. If a 162 transaction passes the validation, then CometBFT adds it to the mempool; otherwise the 163 transaction is discarded. 164 CometBFT calls it when it receives a new transaction either coming from an external 165 user (e.g., a client) or another node. Furthermore, CometBFT can be configured to call 166 re-`CheckTx` on all outstanding transactions in the mempool after calling `Commit` for a block. 167 168 ### Info methods 169 170 - [**Info:**](./abci++_methods.md#info) Used to sync CometBFT with the Application during a 171 handshake that happens upon recovery, or on startup when state-sync is used. 172 173 - [**Query:**](./abci++_methods.md#query) This method can be used to query the Application for 174 information about the application state. 175 176 ### State-sync methods 177 178 State sync allows new nodes to rapidly bootstrap by discovering, fetching, and applying 179 state machine (application) snapshots instead of replaying historical blocks. For more details, see the 180 [state sync documentation](../p2p/legacy-docs/messages/state-sync.md). 181 182 New nodes discover and request snapshots from other nodes in the P2P network. 183 A CometBFT node that receives a request for snapshots from a peer will call 184 `ListSnapshots` on its Application. The Application returns the list of locally available 185 snapshots. 186 Note that the list does not contain the actual snapshots but metadata about them: height at which 187 the snapshot was taken, application-specific verification data and more (see 188 [snapshot data type](./abci++_methods.md#snapshot) for more details). After receiving a 189 list of available snapshots from a peer, the new node can offer any of the snapshots in the list to 190 its local Application via the `OfferSnapshot` method. The Application can check at this point the 191 validity of the snapshot metadata. 192 193 Snapshots may be quite large and are thus broken into smaller "chunks" that can be 194 assembled into the whole snapshot. Once the Application accepts a snapshot and 195 begins restoring it, CometBFT will fetch snapshot "chunks" from existing nodes. 196 The node providing "chunks" will fetch them from its local Application using 197 the `LoadSnapshotChunk` method. 198 199 As the new node receives "chunks" it will apply them sequentially to the local 200 application with `ApplySnapshotChunk`. When all chunks have been applied, the 201 Application's `AppHash` is retrieved via an `Info` query. 202 To ensure that the sync proceeded correctly, CometBFT compares the local Application's `AppHash` 203 to the `AppHash` stored on the blockchain (verified via 204 [light client verification](../light-client/verification/README.md)). 205 206 In summary: 207 208 - [**ListSnapshots:**](./abci++_methods.md#listsnapshots) Used by nodes to discover available 209 snapshots on peers. 210 211 - [**OfferSnapshot:**](./abci++_methods.md#offersnapshot) When a node receives a snapshot from a 212 peer, CometBFT uses this method to offer the snapshot to the Application. 213 214 - [**LoadSnapshotChunk:**](./abci++_methods.md#loadsnapshotchunk) Used by CometBFT to retrieve 215 snapshot chunks from the Application to send to peers. 216 217 - [**ApplySnapshotChunk:**](./abci++_methods.md#applysnapshotchunk) Used by CometBFT to hand 218 snapshot chunks to the Application. 219 220 ### Other methods 221 222 Additionally, there is a [**Flush**](./abci++_methods.md#flush) method that is called on every connection, 223 and an [**Echo**](./abci++_methods.md#echo) method that is used for debugging. 224 225 More details on managing state across connections can be found in the section on 226 [Managing Application State](./abci%2B%2B_app_requirements.md#managing-the-application-state-and-related-topics). 227 228 ## Proposal timeout 229 230 `PrepareProposal` stands on the consensus algorithm critical path, 231 i.e., CometBFT cannot make progress while this method is being executed. 232 Hence, if the Application takes a long time preparing a proposal, 233 the default value of *TimeoutPropose* might not be sufficient 234 to accommodate the method's execution and validator nodes might time out and prevote `nil`. 235 The proposal, in this case, will probably be rejected and a new round will be necessary. 236 237 Timeouts are automatically increased for each new round of a height and, if the execution of `PrepareProposal` is bound, eventually *TimeoutPropose* will be long enough to accommodate the execution of `PrepareProposal`. 238 However, relying on this self adaptation could lead to performance degradation and, therefore, 239 operators are suggested to adjust the initial value of *TimeoutPropose* in CometBFT's configuration file, 240 in order to suit the needs of the particular application being deployed. 241 242 This is particularly important if applications implement *immediate execution*. 243 To implement this technique, proposers need to execute the block being proposed within `PrepareProposal`, which could take longer than *TimeoutPropose*. 244 245 ## Deterministic State-Machine Replication 246 247 [↑ Back to Outline](#outline) 248 249 ABCI applications must implement deterministic finite-state machines to be 250 securely replicated by the CometBFT consensus engine. This means block execution 251 must be strictly deterministic: given the same 252 ordered set of transactions, all nodes will compute identical responses, for all 253 successive `BeginBlock`, `DeliverTx`, `EndBlock`, and `Commit` calls. This is critical because the 254 responses are included in the header of the next block, either via a Merkle root 255 or directly, so all nodes must agree on exactly what they are. 256 257 For this reason, it is recommended that application state is not exposed to any 258 external user or process except via the ABCI connections to a consensus engine 259 like CometBFT. The Application must only change its state based on input 260 from block execution (`BeginBlock`, `DeliverTx`, `EndBlock`, and `Commit` calls), and not through 261 any other kind of request. This is the only way to ensure all nodes see the same 262 transactions and compute the same results. 263 264 Applications that implement immediate execution (execute the blocks 265 that are about to be proposed, in `PrepareProposal`, or that require validation, in `ProcessProposal`) produce a new candidate state before a block is decided. 266 The state changes caused by processing those 267 proposed blocks must never replace the previous state until `FinalizeBlock` confirms 268 that the proposed block was decided and `Commit` is invoked for it. 269 270 The same is true to Applications that quickly accept blocks and execute the blocks optimistically in parallel with the remaining consensus steps to save time during block execution (`BeginBlock`, `DeliverTx`, `EndBlock`, and `Commit` calls); they must only apply state changes in `Commit`. 271 272 <!-- 273 Additionally, vote extensions or the validation thereof (via `ExtendVote` or 274 `VerifyVoteExtension`) must *never* have side effects on the current state. 275 They can only be used when their data is provided in a `RequestPrepareProposal` call. 276 --> 277 If there is some non-determinism in the state machine, consensus will eventually 278 fail as nodes disagree over the correct values for the block header. The 279 non-determinism must be fixed and the nodes restarted. 280 281 Sources of non-determinism in applications may include: 282 283 - Hardware failures 284 - Cosmic rays, overheating, etc. 285 - Node-dependent state 286 - Random numbers 287 - Time 288 - Underspecification 289 - Library version changes 290 - Race conditions 291 - Floating point numbers 292 - JSON or protobuf serialization 293 - Iterating through hash-tables/maps/dictionaries 294 - External Sources 295 - Filesystem 296 - Network calls (eg. some external REST API service) 297 298 See [#56](https://github.com/tendermint/abci/issues/56) for the original discussion. 299 300 Note that some methods (`Query, DeliverTx`) return non-deterministic data in the form 301 of `Info` and `Log` fields. The `Log` is intended for the literal output from the Application's 302 logger, while the `Info` is any additional info that should be returned. These are the only fields 303 that are not included in block header computations, so we don't need agreement 304 on them. All other fields in the `Response*` must be strictly deterministic. 305 306 ## Events 307 308 [↑ Back to Outline](#outline) 309 310 Methods `BeginBlock, DeliverTx` and `EndBlock` include an `events` field in their 311 `Response*`. 312 Applications may respond to this ABCI 2.0 method with an event list for each executed 313 transaction, and a general event list for the block itself. 314 Events allow applications to associate metadata with transactions and blocks. 315 Events returned via these ABCI methods do not impact the consensus algorithm in any way 316 and instead exist to power subscriptions and queries of CometBFT state. 317 318 An `Event` contains a `type` and a list of `EventAttributes`, which are key-value 319 string pairs denoting metadata about what happened during the method's (or transaction's) 320 execution. `Event` values can be used to index transactions and blocks according to what 321 happened during their execution. 322 323 Each event has a `type` which is meant to categorize the event for a particular 324 `Response*` or `Tx`. A `Response*` or `Tx` may contain multiple events with duplicate 325 `type` values, where each distinct entry is meant to categorize attributes for a 326 particular event. Every key and value in an event's attributes must be UTF-8 327 encoded strings along with the event type itself. 328 329 ```protobuf 330 message Event { 331 string type = 1; 332 repeated EventAttribute attributes = 2; 333 } 334 ``` 335 336 The attributes of an `Event` consist of a `key`, a `value`, and an `index` flag. The 337 index flag notifies the CometBFT indexer to index the attribute. The value of 338 the `index` flag is non-deterministic and may vary across different nodes in the network. 339 340 ```protobuf 341 message EventAttribute { 342 string key = 1; 343 string value = 2; 344 bool index = 3; // nondeterministic 345 } 346 ``` 347 348 Example: 349 350 ```go 351 abci.ResponseDeliverTx{ 352 // ... 353 Events: []abci.Event{ 354 { 355 Type: "validator.provisions", 356 Attributes: []abci.EventAttribute{ 357 abci.EventAttribute{Key: "address", Value: "...", Index: true}, 358 abci.EventAttribute{Key: "amount", Value: "...", Index: true}, 359 abci.EventAttribute{Key: "balance", Value: "...", Index: true}, 360 }, 361 }, 362 { 363 Type: "validator.provisions", 364 Attributes: []abci.EventAttribute{ 365 abci.EventAttribute{Key: "address", Value: "...", Index: true}, 366 abci.EventAttribute{Key: "amount", Value: "...", Index: false}, 367 abci.EventAttribute{Key: "balance", Value: "...", Index: false}, 368 }, 369 }, 370 { 371 Type: "validator.slashed", 372 Attributes: []abci.EventAttribute{ 373 abci.EventAttribute{Key: "address", Value: "...", Index: false}, 374 abci.EventAttribute{Key: "amount", Value: "...", Index: true}, 375 abci.EventAttribute{Key: "reason", Value: "...", Index: true}, 376 }, 377 }, 378 // ... 379 }, 380 } 381 ``` 382 383 ## Evidence 384 385 [↑ Back to Outline](#outline) 386 387 CometBFT's security model relies on the use of evidences of misbehavior. An evidence is an 388 irrefutable proof of malicious behavior by a network participant. It is the responsibility of 389 CometBFT to detect such malicious behavior. When malicious behavior is detected, CometBFT 390 will gossip evidences of misbehavior to other nodes and commit the evidences to 391 the chain once they are verified by a subset of validators. These evidences will then be 392 passed on to the Application through ABCI++. It is the responsibility of the 393 Application to handle evidence of misbehavior and exercise punishment. 394 395 There are two forms of evidence: Duplicate Vote and Light Client Attack. More 396 information can be found in either [data structures](../core/data_structures.md) 397 or [accountability](../light-client/accountability/). 398 399 EvidenceType has the following protobuf format: 400 401 ```protobuf 402 enum EvidenceType { 403 UNKNOWN = 0; 404 DUPLICATE_VOTE = 1; 405 LIGHT_CLIENT_ATTACK = 2; 406 } 407 ``` 408 409 ## Errors 410 411 [↑ Back to Outline](#outline) 412 413 The `Query`, `CheckTx` and `DeliverTx` methods include a `Code` field in their `Response*`. 414 Field `Code` is meant to contain an application-specific response code. 415 A response code of `0` indicates no error. Any other response code 416 indicates to CometBFT that an error occurred. 417 418 These methods also return a `Codespace` string to CometBFT. This field is 419 used to disambiguate `Code` values returned by different domains of the 420 Application. The `Codespace` is a namespace for the `Code`. 421 422 Methods `Echo`, `Info`, `BeginBlock`, `EndBlock`, `Commit` and `InitChain` do not return errors. 423 An error in any of these methods represents a critical issue that CometBFT 424 has no reasonable way to handle. If there is an error in one 425 of these methods, the Application must crash to ensure that the error is safely 426 handled by an operator. 427 428 <!-- 429 Method `FinalizeBlock` is a special case. It contains a number of 430 `Code` and `Codespace` fields as part of type `ExecTxResult`. Each of 431 these codes reports errors related to the transaction it is attached to. 432 However, `FinalizeBlock` does not return errors at the top level, so the 433 same considerations on critical issues made for `Echo`, `Info`, and 434 `InitChain` also apply here. 435 --> 436 437 The handling of non-zero response codes by CometBFT is described below. 438 439 ### `CheckTx` 440 441 When CometBFT receives a `ResponseCheckTx` with a non-zero `Code`, the associated 442 transaction will not be added to CometBFT's mempool or it will be removed if 443 it is already included. 444 445 ### `DeliverTx` 446 447 The `DeliverTx` ABCI method delivers transactions from CometBFT to the application. 448 When CometBFT receives a `ResponseDeliverTx` with a non-zero `Code`, the response code is logged. 449 The transaction was already included in a block, so the `Code` does not influence consensus. 450 451 <!-- 452 The `ExecTxResult` type delivers transaction results from the Application to CometBFT. When 453 CometBFT receives a `ResponseFinalizeBlock` containing an `ExecTxResult` with a non-zero `Code`, 454 the response code is logged. Past `Code` values can be queried by clients. As the transaction was 455 part of a decided block, the `Code` does not influence consensus. 456 --> 457 458 ### `Query` 459 460 When CometBFT receives a `ResponseQuery` with a non-zero `Code`, this code is 461 returned directly to the client that initiated the query.