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