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.