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