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  [&#8593; 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  [&#8593; 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  [&#8593; 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  [&#8593; 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  [&#8593; 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.