github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/spec/abci/apps.md (about)

     1  ---
     2  order: 2
     3  title: Applications
     4  ---
     5  
     6  # Applications
     7  
     8  Please ensure you've first read the spec for [ABCI Methods and Types](abci.md)
     9  
    10  Here we cover the following components of ABCI applications:
    11  
    12  - [Connection State](#connection-state) - the interplay between ABCI connections and application state
    13    and the differences between `CheckTx` and `DeliverTx`.
    14  - [Transaction Results](#transaction-results) - rules around transaction
    15    results and validity
    16  - [Validator Set Updates](#updating-the-validator-set) - how validator sets are
    17    changed during `InitChain` and `EndBlock`
    18  - [Query](#query) - standards for using the `Query` method and proofs about the
    19    application state
    20  - [Crash Recovery](#crash-recovery) - handshake protocol to synchronize
    21    Tendermint and the application on startup.
    22  - [State Sync](#state-sync) - rapid bootstrapping of new nodes by restoring state machine snapshots
    23  
    24  ## Connection State
    25  
    26  Since Tendermint maintains four concurrent ABCI connections, it is typical
    27  for an application to maintain a distinct state for each, and for the states to
    28  be synchronized during `Commit`.
    29  
    30  ### Concurrency
    31  
    32  In principle, each of the four ABCI connections operate concurrently with one
    33  another. This means applications need to ensure access to state is
    34  thread safe. In practice, both the
    35  [default in-process ABCI client](https://github.com/tendermint/tendermint/blob/v0.34.4/abci/client/local_client.go#L18)
    36  and the
    37  [default Go ABCI
    38  server](https://github.com/tendermint/tendermint/blob/v0.34.4/abci/server/socket_server.go#L32)
    39  use global locks across all connections, so they are not
    40  concurrent at all. This means if your app is written in Go, and compiled in-process with Tendermint
    41  using the default `NewLocalClient`, or run out-of-process using the default `SocketServer`,
    42  ABCI messages from all connections will be linearizable (received one at a
    43  time).
    44  
    45  The existence of this global mutex means Go application developers can get
    46  thread safety for application state by routing *all* reads and writes through the ABCI
    47  system. Thus it may be *unsafe* to expose application state directly to an RPC
    48  interface, and unless explicit measures are taken, all queries should be routed through the ABCI Query method.
    49  
    50  ### BeginBlock
    51  
    52  The BeginBlock request can be used to run some code at the beginning of
    53  every block. It also allows Tendermint to send the current block hash
    54  and header to the application, before it sends any of the transactions.
    55  
    56  The app should remember the latest height and header (ie. from which it
    57  has run a successful Commit) so that it can tell Tendermint where to
    58  pick up from when it restarts. See information on the Handshake, below.
    59  
    60  ### Commit
    61  
    62  Application state should only be persisted to disk during `Commit`.
    63  
    64  Before `Commit` is called, Tendermint locks and flushes the mempool so that no new messages will
    65  be received on the mempool connection. This provides an opportunity to safely update all four connection
    66  states to the latest committed state at once.
    67  
    68  When `Commit` completes, it unlocks the mempool.
    69  
    70  WARNING: if the ABCI app logic processing the `Commit` message sends a
    71  `/broadcast_tx_sync` or `/broadcast_tx_commit` and waits for the response
    72  before proceeding, it will deadlock. Executing those `broadcast_tx` calls
    73  involves acquiring a lock that is held during the `Commit` call, so it's not
    74  possible. If you make the call to the `broadcast_tx` endpoints concurrently,
    75  that's no problem, it just can't be part of the sequential logic of the
    76  `Commit` function.
    77  
    78  ### Consensus Connection
    79  
    80  The Consensus Connection should maintain a `DeliverTxState` - the working state
    81  for block execution. It should be updated by the calls to `BeginBlock`, `DeliverTx`,
    82  and `EndBlock` during block execution and committed to disk as the "latest
    83  committed state" during `Commit`.
    84  
    85  Updates made to the `DeliverTxState` by each method call must be readable by each subsequent method -
    86  ie. the updates are linearizable.
    87  
    88  ### Mempool Connection
    89  
    90  The mempool Connection should maintain a `CheckTxState`
    91  to sequentially process pending transactions in the mempool that have
    92  not yet been committed. It should be initialized to the latest committed state
    93  at the end of every `Commit`.
    94  
    95  Before calling `Commit`, Tendermint will lock and flush the mempool connection,
    96  ensuring that all existing CheckTx are responded to and no new ones can begin.
    97  The `CheckTxState` may be updated concurrently with the `DeliverTxState`, as
    98  messages may be sent concurrently on the Consensus and Mempool connections.
    99  
   100  After `Commit`, while still holding the mempool lock, CheckTx is run again on all transactions that remain in the
   101  node's local mempool after filtering those included in the block.
   102  An additional `Type` parameter is made available to the CheckTx function that
   103  indicates whether an incoming transaction is new (`CheckTxType_New`), or a
   104  recheck (`CheckTxType_Recheck`).
   105  
   106  Finally, after re-checking transactions in the mempool, Tendermint will unlock
   107  the mempool connection. New transactions are once again able to be processed through CheckTx.
   108  
   109  Note that CheckTx is just a weak filter to keep invalid transactions out of the block chain.
   110  CheckTx doesn't have to check everything that affects transaction validity; the
   111  expensive things can be skipped.  It's weak because a Byzantine node doesn't
   112  care about CheckTx; it can propose a block full of invalid transactions if it wants.
   113  
   114  #### Replay Protection
   115  
   116  To prevent old transactions from being replayed, CheckTx must implement
   117  replay protection.
   118  
   119  It is possible for old transactions to be sent to the application. So
   120  it is important CheckTx implements some logic to handle them.
   121  
   122  ### Query Connection
   123  
   124  The Info Connection should maintain a `QueryState` for answering queries from the user,
   125  and for initialization when Tendermint first starts up (both described further
   126  below).
   127  It should always contain the latest committed state associated with the
   128  latest committed block.
   129  
   130  `QueryState` should be set to the latest `DeliverTxState` at the end of every `Commit`,
   131  after the full block has been processed and the state committed to disk.
   132  Otherwise it should never be modified.
   133  
   134  Tendermint Core currently uses the Query connection to filter peers upon
   135  connecting, according to IP address or node ID. For instance,
   136  returning non-OK ABCI response to either of the following queries will
   137  cause Tendermint to not connect to the corresponding peer:
   138  
   139  - `p2p/filter/addr/<ip addr>`, where `<ip addr>` is an IP address.
   140  - `p2p/filter/id/<id>`, where `<is>` is the hex-encoded node ID (the hash of
   141    the node's p2p pubkey).
   142  
   143  Note: these query formats are subject to change!
   144  
   145  ### Snapshot Connection
   146  
   147  The Snapshot Connection is optional, and is only used to serve state sync snapshots for other nodes
   148  and/or restore state sync snapshots to a local node being bootstrapped.
   149  
   150  For more information, see [the state sync section of this document](#state-sync).
   151  
   152  ## Transaction Results
   153  
   154  The `Info` and `Log` fields are non-deterministic values for debugging/convenience purposes
   155  that are otherwise ignored.
   156  
   157  The `Data` field must be strictly deterministic, but can be arbitrary data.
   158  
   159  ### Gas
   160  
   161  Ethereum introduced the notion of `gas` as an abstract representation of the
   162  cost of resources used by nodes when processing transactions. Every operation in the
   163  Ethereum Virtual Machine uses some amount of gas, and gas can be accepted at a market-variable price.
   164  Users propose a maximum amount of gas for their transaction; if the tx uses less, they get
   165  the difference credited back. Tendermint adopts a similar abstraction,
   166  though uses it only optionally and weakly, allowing applications to define
   167  their own sense of the cost of execution.
   168  
   169  In Tendermint, the
   170  [ConsensusParams.Block.MaxGas](../../proto/tendermint/types/params.proto)
   171  limits the amount of `gas` that can be used in a block.  The default value is
   172  `-1`, meaning no limit, or that the concept of gas is meaningless.
   173  
   174  Responses contain a `GasWanted` and `GasUsed` field. The former is the maximum
   175  amount of gas the sender of a tx is willing to use, and the later is how much it actually
   176  used. Applications should enforce that `GasUsed <= GasWanted` - ie. tx execution
   177  should halt before it can use more resources than it requested.
   178  
   179  When `MaxGas > -1`, Tendermint enforces the following rules:
   180  
   181  - `GasWanted <= MaxGas` for all txs in the mempool
   182  - `(sum of GasWanted in a block) <= MaxGas` when proposing a block
   183  
   184  If `MaxGas == -1`, no rules about gas are enforced.
   185  
   186  Note that Tendermint does not currently enforce anything about Gas in the consensus, only the mempool.
   187  This means it does not guarantee that committed blocks satisfy these rules!
   188  It is the application's responsibility to return non-zero response codes when gas limits are exceeded.
   189  
   190  The `GasUsed` field is ignored completely by Tendermint. That said, applications should enforce:
   191  
   192  - `GasUsed <= GasWanted` for any given transaction
   193  - `(sum of GasUsed in a block) <= MaxGas` for every block
   194  
   195  In the future, we intend to add a `Priority` field to the responses that can be
   196  used to explicitly prioritize txs in the mempool for inclusion in a block
   197  proposal. See [#1861](https://github.com/tendermint/tendermint/issues/1861).
   198  
   199  ### CheckTx
   200  
   201  If `Code != 0`, it will be rejected from the mempool and hence
   202  not broadcasted to other peers and not included in a proposal block.
   203  
   204  `Data` contains the result of the CheckTx transaction execution, if any. It is
   205  semantically meaningless to Tendermint.
   206  
   207  ### DeliverTx
   208  
   209  DeliverTx is the workhorse of the blockchain. Tendermint sends the
   210  DeliverTx requests asynchronously but in order, and relies on the
   211  underlying socket protocol (ie. TCP) to ensure they are received by the
   212  app in order. They have already been ordered in the global consensus by
   213  the Tendermint protocol.
   214  
   215  If DeliverTx returns `Code != 0`, the transaction will be considered invalid,
   216  though it is still included in the block.
   217  
   218  DeliverTx also returns a [Code, Data, and Log](../../proto/tendermint/abci/types.proto#L189-L191).
   219  
   220  `Data` contains the result of the CheckTx transaction execution, if any. It is
   221  semantically meaningless to Tendermint.
   222  
   223  Both the `Code` and `Data` are included in a structure that is hashed into the
   224  `LastResultsHash` of the next block header.
   225  
   226  `Events` include any events for the execution, which Tendermint will use to index
   227  the transaction by. This allows transactions to be queried according to what
   228  events took place during their execution.
   229  
   230  ## Updating the Validator Set
   231  
   232  The application may set the validator set during InitChain, and may update it during
   233  EndBlock.
   234  
   235  Note that the maximum total power of the validator set is bounded by
   236  `MaxTotalVotingPower = MaxInt64 / 8`. Applications are responsible for ensuring
   237  they do not make changes to the validator set that cause it to exceed this
   238  limit.
   239  
   240  Additionally, applications must ensure that a single set of updates does not contain any duplicates -
   241  a given public key can only appear once within a given update. If an update includes
   242  duplicates, the block execution will fail irrecoverably.
   243  
   244  ### InitChain
   245  
   246  The `InitChain` method can return a list of validators.
   247  If the list is empty, Tendermint will use the validators loaded in the genesis
   248  file.
   249  If the list returned by `InitChain` is not empty, Tendermint will use its contents as the validator set.
   250  This way the application can set the initial validator set for the
   251  blockchain.
   252  
   253  ### EndBlock
   254  
   255  Updates to the Tendermint validator set can be made by returning
   256  `ValidatorUpdate` objects in the `ResponseEndBlock`:
   257  
   258  ```protobuf
   259  message ValidatorUpdate {
   260    tendermint.crypto.keys.PublicKey pub_key
   261    int64 power
   262  }
   263  
   264  message PublicKey {
   265    oneof {
   266      ed25519 bytes = 1;
   267    }
   268  ```
   269  
   270  The `pub_key` currently supports only one type:
   271  
   272  - `type = "ed25519"`
   273  
   274  The `power` is the new voting power for the validator, with the
   275  following rules:
   276  
   277  - power must be non-negative
   278  - if power is 0, the validator must already exist, and will be removed from the
   279    validator set
   280  - if power is non-0:
   281      - if the validator does not already exist, it will be added to the validator
   282      set with the given power
   283      - if the validator does already exist, its power will be adjusted to the given power
   284  - the total power of the new validator set must not exceed MaxTotalVotingPower
   285  
   286  Note the updates returned in block `H` will only take effect at block `H+2`.
   287  
   288  ## Consensus Parameters
   289  
   290  ConsensusParams enforce certain limits in the blockchain, like the maximum size
   291  of blocks, amount of gas used in a block, and the maximum acceptable age of
   292  evidence. They can be set in InitChain and updated in EndBlock.
   293  
   294  ### BlockParams.MaxBytes
   295  
   296  The maximum size of a complete Protobuf encoded block.
   297  This is enforced by Tendermint consensus.
   298  
   299  This implies a maximum transaction size that is this MaxBytes, less the expected size of
   300  the header, the validator set, and any included evidence in the block.
   301  
   302  Must have `0 < MaxBytes < 100 MB`.
   303  
   304  ### BlockParams.MaxGas
   305  
   306  The maximum of the sum of `GasWanted` that will be allowed in a proposed block.
   307  This is *not* enforced by Tendermint consensus.
   308  It is left to the app to enforce (ie. if txs are included past the
   309  limit, they should return non-zero codes). It is used by Tendermint to limit the
   310  txs included in a proposed block.
   311  
   312  Must have `MaxGas >= -1`.
   313  If `MaxGas == -1`, no limit is enforced.
   314  
   315  ### BlockParams.RecheckTx
   316  
   317  This indicates whether all nodes in the network should perform a `CheckTx` on all
   318  transactions remaining in the mempool directly *after* the execution of every block,
   319  i.e. whenever a new application state is created. This is often useful for garbage
   320  collection.
   321  
   322  The change will come into effect immediately after `FinalizeBlock` has been
   323  called.
   324  
   325  This was previously a local mempool config parameter.
   326  
   327  ### EvidenceParams.MaxAgeDuration
   328  
   329  This is the maximum age of evidence in time units.
   330  This is enforced by Tendermint consensus.
   331  
   332  If a block includes evidence older than this (AND the evidence was created more
   333  than `MaxAgeNumBlocks` ago), the block will be rejected (validators won't vote
   334  for it).
   335  
   336  Must have `MaxAgeDuration > 0`.
   337  
   338  ### EvidenceParams.MaxAgeNumBlocks
   339  
   340  This is the maximum age of evidence in blocks.
   341  This is enforced by Tendermint consensus.
   342  
   343  If a block includes evidence older than this (AND the evidence was created more
   344  than `MaxAgeDuration` ago), the block will be rejected (validators won't vote
   345  for it).
   346  
   347  Must have `MaxAgeNumBlocks > 0`.
   348  
   349  ### EvidenceParams.MaxNum
   350  
   351  This is the maximum number of evidence that can be committed to a single block.
   352  
   353  The product of this and the `MaxEvidenceBytes` must not exceed the size of
   354  a block minus it's overhead ( ~ `MaxBytes`).
   355  
   356  Must have `MaxNum > 0`.
   357  
   358  ### SynchronyParams.Precision
   359  
   360  `SynchronyParams.Precision` is a parameter of the Proposer-Based Timestamps algorithm.
   361  that configures the acceptable upper-bound of clock drift among
   362  all of the nodes on a Tendermint network. Any two nodes on a Tendermint network
   363  are expected to have clocks that differ by at most `Precision`.
   364  
   365  ### SynchronyParams.MessageDelay
   366  
   367  `SynchronyParams.MessageDelay` is a parameter of the Proposer-Based Timestamps
   368  algorithm that configures the acceptable upper-bound for transmitting a `Proposal`
   369  message from the proposer to all of the validators on the network.
   370  
   371  ### Updates
   372  
   373  The application may set the ConsensusParams during InitChain, and update them during
   374  EndBlock. If the ConsensusParams is empty, it will be ignored. Each field
   375  that is not empty will be applied in full. For instance, if updating the
   376  Block.MaxBytes, applications must also set the other Block fields (like
   377  Block.MaxGas), even if they are unchanged, as they will otherwise cause the
   378  value to be updated to 0.
   379  
   380  #### InitChain
   381  
   382  ResponseInitChain includes a ConsensusParams.
   383  If ConsensusParams is nil, Tendermint will use the params loaded in the genesis
   384  file. If ConsensusParams is not nil, Tendermint will use it.
   385  This way the application can determine the initial consensus params for the
   386  blockchain.
   387  
   388  #### EndBlock
   389  
   390  ResponseEndBlock includes a ConsensusParams.
   391  If ConsensusParams nil, Tendermint will do nothing.
   392  If ConsensusParam is not nil, Tendermint will use it.
   393  This way the application can update the consensus params over time.
   394  
   395  Note the updates returned in block `H` will take effect right away for block
   396  `H+1`.
   397  
   398  ## Query
   399  
   400  Query is a generic method with lots of flexibility to enable diverse sets
   401  of queries on application state. Tendermint makes use of Query to filter new peers
   402  based on ID and IP, and exposes Query to the user over RPC.
   403  
   404  Note that calls to Query are not replicated across nodes, but rather query the
   405  local node's state - hence they may return stale reads. For reads that require
   406  consensus, use a transaction.
   407  
   408  The most important use of Query is to return Merkle proofs of the application state at some height
   409  that can be used for efficient application-specific light-clients.
   410  
   411  Note Tendermint has technically no requirements from the Query
   412  message for normal operation - that is, the ABCI app developer need not implement
   413  Query functionality if they do not wish too.
   414  
   415  ### Query Proofs
   416  
   417  The Tendermint block header includes a number of hashes, each providing an
   418  anchor for some type of proof about the blockchain. The `ValidatorsHash` enables
   419  quick verification of the validator set, the `DataHash` gives quick
   420  verification of the transactions included in the block, etc.
   421  
   422  The `AppHash` is unique in that it is application specific, and allows for
   423  application-specific Merkle proofs about the state of the application.
   424  While some applications keep all relevant state in the transactions themselves
   425  (like Bitcoin and its UTXOs), others maintain a separated state that is
   426  computed deterministically *from* transactions, but is not contained directly in
   427  the transactions themselves (like Ethereum contracts and accounts).
   428  For such applications, the `AppHash` provides a much more efficient way to verify light-client proofs.
   429  
   430  ABCI applications can take advantage of more efficient light-client proofs for
   431  their state as follows:
   432  
   433  - return the Merkle root of the deterministic application state in
   434  `ResponseCommit.Data`. This Merkle root will be included as the `AppHash` in the next block.
   435  - return efficient Merkle proofs about that application state in `ResponseQuery.Proof`
   436    that can be verified using the `AppHash` of the corresponding block.
   437  
   438  For instance, this allows an application's light-client to verify proofs of
   439  absence in the application state, something which is much less efficient to do using the block hash.
   440  
   441  Some applications (eg. Ethereum, Cosmos-SDK) have multiple "levels" of Merkle trees,
   442  where the leaves of one tree are the root hashes of others. To support this, and
   443  the general variability in Merkle proofs, the `ResponseQuery.Proof` has some minimal structure:
   444  
   445  ```protobuf
   446  message ProofOps {
   447    repeated ProofOp ops
   448  }
   449  
   450  message ProofOp {
   451    string type = 1;
   452    bytes key = 2;
   453    bytes data = 3;
   454  }
   455  ```
   456  
   457  Each `ProofOp` contains a proof for a single key in a single Merkle tree, of the specified `type`.
   458  This allows ABCI to support many different kinds of Merkle trees, encoding
   459  formats, and proofs (eg. of presence and absence) just by varying the `type`.
   460  The `data` contains the actual encoded proof, encoded according to the `type`.
   461  When verifying the full proof, the root hash for one ProofOp is the value being
   462  verified for the next ProofOp in the list. The root hash of the final ProofOp in
   463  the list should match the `AppHash` being verified against.
   464  
   465  ### Peer Filtering
   466  
   467  When Tendermint connects to a peer, it sends two queries to the ABCI application
   468  using the following paths, with no additional data:
   469  
   470  - `/p2p/filter/addr/<IP:PORT>`, where `<IP:PORT>` denote the IP address and
   471    the port of the connection
   472  - `p2p/filter/id/<ID>`, where `<ID>` is the peer node ID (ie. the
   473    pubkey.Address() for the peer's PubKey)
   474  
   475  If either of these queries return a non-zero ABCI code, Tendermint will refuse
   476  to connect to the peer.
   477  
   478  ### Paths
   479  
   480  Queries are directed at paths, and may optionally include additional data.
   481  
   482  The expectation is for there to be some number of high level paths
   483  differentiating concerns, like `/p2p`, `/store`, and `/app`. Currently,
   484  Tendermint only uses `/p2p`, for filtering peers. For more advanced use, see the
   485  implementation of
   486  [Query in the Cosmos-SDK](https://github.com/cosmos/cosmos-sdk/blob/v0.23.1/baseapp/baseapp.go#L333).
   487  
   488  ## Crash Recovery
   489  
   490  On startup, Tendermint calls the `Info` method on the Info Connection to get the latest
   491  committed state of the app. The app MUST return information consistent with the
   492  last block it succesfully completed Commit for.
   493  
   494  If the app succesfully committed block H, then `last_block_height = H` and `last_block_app_hash = <hash returned by Commit for block H>`. If the app
   495  failed during the Commit of block H, then `last_block_height = H-1` and
   496  `last_block_app_hash = <hash returned by Commit for block H-1, which is the hash in the header of block H>`.
   497  
   498  We now distinguish three heights, and describe how Tendermint syncs itself with
   499  the app.
   500  
   501  ```md
   502  storeBlockHeight = height of the last block Tendermint saw a commit for
   503  stateBlockHeight = height of the last block for which Tendermint completed all
   504      block processing and saved all ABCI results to disk
   505  appBlockHeight = height of the last block for which ABCI app succesfully
   506      completed Commit
   507  
   508  ```
   509  
   510  Note we always have `storeBlockHeight >= stateBlockHeight` and `storeBlockHeight >= appBlockHeight`
   511  Note also Tendermint never calls Commit on an ABCI app twice for the same height.
   512  
   513  The procedure is as follows.
   514  
   515  First, some simple start conditions:
   516  
   517  If `appBlockHeight == 0`, then call InitChain.
   518  
   519  If `storeBlockHeight == 0`, we're done.
   520  
   521  Now, some sanity checks:
   522  
   523  If `storeBlockHeight < appBlockHeight`, error
   524  If `storeBlockHeight < stateBlockHeight`, panic
   525  If `storeBlockHeight > stateBlockHeight+1`, panic
   526  
   527  Now, the meat:
   528  
   529  If `storeBlockHeight == stateBlockHeight && appBlockHeight < storeBlockHeight`,
   530  replay all blocks in full from `appBlockHeight` to `storeBlockHeight`.
   531  This happens if we completed processing the block, but the app forgot its height.
   532  
   533  If `storeBlockHeight == stateBlockHeight && appBlockHeight == storeBlockHeight`, we're done.
   534  This happens if we crashed at an opportune spot.
   535  
   536  If `storeBlockHeight == stateBlockHeight+1`
   537  This happens if we started processing the block but didn't finish.
   538  
   539  If `appBlockHeight < stateBlockHeight`
   540      replay all blocks in full from `appBlockHeight` to `storeBlockHeight-1`,
   541      and replay the block at `storeBlockHeight` using the WAL.
   542  This happens if the app forgot the last block it committed.
   543  
   544  If `appBlockHeight == stateBlockHeight`,
   545      replay the last block (storeBlockHeight) in full.
   546  This happens if we crashed before the app finished Commit
   547  
   548  If `appBlockHeight == storeBlockHeight`
   549      update the state using the saved ABCI responses but dont run the block against the real app.
   550  This happens if we crashed after the app finished Commit but before Tendermint saved the state.
   551  
   552  ## State Sync
   553  
   554  A new node joining the network can simply join consensus at the genesis height and replay all
   555  historical blocks until it is caught up. However, for large chains this can take a significant
   556  amount of time, often on the order of days or weeks.
   557  
   558  State sync is an alternative mechanism for bootstrapping a new node, where it fetches a snapshot
   559  of the state machine at a given height and restores it. Depending on the application, this can
   560  be several orders of magnitude faster than replaying blocks.
   561  
   562  Note that state sync does not currently backfill historical blocks, so the node will have a
   563  truncated block history - users are advised to consider the broader network implications of this in
   564  terms of block availability and auditability. This functionality may be added in the future.
   565  
   566  For details on the specific ABCI calls and types, see the [methods and types section](abci.md).
   567  
   568  ### Taking Snapshots
   569  
   570  Applications that want to support state syncing must take state snapshots at regular intervals. How
   571  this is accomplished is entirely up to the application. A snapshot consists of some metadata and
   572  a set of binary chunks in an arbitrary format:
   573  
   574  - `Height (uint64)`: The height at which the snapshot is taken. It must be taken after the given
   575    height has been committed, and must not contain data from any later heights.
   576  
   577  - `Format (uint32)`: An arbitrary snapshot format identifier. This can be used to version snapshot
   578    formats, e.g. to switch from Protobuf to MessagePack for serialization. The application can use
   579    this when restoring to choose whether to accept or reject a snapshot.
   580  
   581  - `Chunks (uint32)`: The number of chunks in the snapshot. Each chunk contains arbitrary binary
   582    data, and should be less than 16 MB; 10 MB is a good starting point.
   583  
   584  - `Hash ([]byte)`: An arbitrary hash of the snapshot. This is used to check whether a snapshot is
   585    the same across nodes when downloading chunks.
   586  
   587  - `Metadata ([]byte)`: Arbitrary snapshot metadata, e.g. chunk hashes for verification or any other
   588    necessary info.
   589  
   590  For a snapshot to be considered the same across nodes, all of these fields must be identical. When
   591  sent across the network, snapshot metadata messages are limited to 4 MB.
   592  
   593  When a new node is running state sync and discovering snapshots, Tendermint will query an existing
   594  application via the ABCI `ListSnapshots` method to discover available snapshots, and load binary
   595  snapshot chunks via `LoadSnapshotChunk`. The application is free to choose how to implement this
   596  and which formats to use, but must provide the following guarantees:
   597  
   598  - **Consistent:** A snapshot must be taken at a single isolated height, unaffected by
   599    concurrent writes. This can be accomplished by using a data store that supports ACID
   600    transactions with snapshot isolation.
   601  
   602  - **Asynchronous:** Taking a snapshot can be time-consuming, so it must not halt chain progress,
   603    for example by running in a separate thread.
   604  
   605  - **Deterministic:** A snapshot taken at the same height in the same format must be identical
   606    (at the byte level) across nodes, including all metadata. This ensures good availability of
   607    chunks, and that they fit together across nodes.
   608  
   609  A very basic approach might be to use a datastore with MVCC transactions (such as RocksDB),
   610  start a transaction immediately after block commit, and spawn a new thread which is passed the
   611  transaction handle. This thread can then export all data items, serialize them using e.g.
   612  Protobuf, hash the byte stream, split it into chunks, and store the chunks in the file system
   613  along with some metadata - all while the blockchain is applying new blocks in parallel.
   614  
   615  A more advanced approach might include incremental verification of individual chunks against the
   616  chain app hash, parallel or batched exports, compression, and so on.
   617  
   618  Old snapshots should be removed after some time - generally only the last two snapshots are needed
   619  (to prevent the last one from being removed while a node is restoring it).
   620  
   621  ### Bootstrapping a Node
   622  
   623  An empty node can be state synced by setting the configuration option `statesync.enabled =
   624  true`. The node also needs the chain genesis file for basic chain info, and configuration for
   625  light client verification of the restored snapshot: a set of Tendermint RPC servers, and a
   626  trusted header hash and corresponding height from a trusted source, via the `statesync`
   627  configuration section.
   628  
   629  Once started, the node will connect to the P2P network and begin discovering snapshots. These
   630  will be offered to the local application via the `OfferSnapshot` ABCI method. Once a snapshot
   631  is accepted Tendermint will fetch and apply the snapshot chunks. After all chunks have been
   632  successfully applied, Tendermint verifies the app's `AppHash` against the chain using the light
   633  client, then switches the node to normal consensus operation.
   634  
   635  #### Snapshot Discovery
   636  
   637  When the empty node join the P2P network, it asks all peers to report snapshots via the
   638  `ListSnapshots` ABCI call (limited to 10 per node). After some time, the node picks the most
   639  suitable snapshot (generally prioritized by height, format, and number of peers), and offers it
   640  to the application via `OfferSnapshot`. The application can choose a number of responses,
   641  including accepting or rejecting it, rejecting the offered format, rejecting the peer who sent
   642  it, and so on. Tendermint will keep discovering and offering snapshots until one is accepted or
   643  the application aborts.
   644  
   645  #### Snapshot Restoration
   646  
   647  Once a snapshot has been accepted via `OfferSnapshot`, Tendermint begins downloading chunks from
   648  any peers that have the same snapshot (i.e. that have identical metadata fields). Chunks are
   649  spooled in a temporary directory, and then given to the application in sequential order via
   650  `ApplySnapshotChunk` until all chunks have been accepted.
   651  
   652  The method for restoring snapshot chunks is entirely up to the application.
   653  
   654  During restoration, the application can respond to `ApplySnapshotChunk` with instructions for how
   655  to continue. This will typically be to accept the chunk and await the next one, but it can also
   656  ask for chunks to be refetched (either the current one or any number of previous ones), P2P peers
   657  to be banned, snapshots to be rejected or retried, and a number of other responses - see the ABCI
   658  reference for details.
   659  
   660  If Tendermint fails to fetch a chunk after some time, it will reject the snapshot and try a
   661  different one via `OfferSnapshot` - the application can choose whether it wants to support
   662  restarting restoration, or simply abort with an error.
   663  
   664  #### Snapshot Verification
   665  
   666  Once all chunks have been accepted, Tendermint issues an `Info` ABCI call to retrieve the
   667  `LastBlockAppHash`. This is compared with the trusted app hash from the chain, retrieved and
   668  verified using the light client. Tendermint also checks that `LastBlockHeight` corresponds to the
   669  height of the snapshot.
   670  
   671  This verification ensures that an application is valid before joining the network. However, the
   672  snapshot restoration may take a long time to complete, so applications may want to employ additional
   673  verification during the restore to detect failures early. This might e.g. include incremental
   674  verification of each chunk against the app hash (using bundled Merkle proofs), checksums to
   675  protect against data corruption by the disk or network, and so on. However, it is important to
   676  note that the only trusted information available is the app hash, and all other snapshot metadata
   677  can be spoofed by adversaries.
   678  
   679  Apps may also want to consider state sync denial-of-service vectors, where adversaries provide
   680  invalid or harmful snapshots to prevent nodes from joining the network. The application can
   681  counteract this by asking Tendermint to ban peers. As a last resort, node operators can use
   682  P2P configuration options to whitelist a set of trusted peers that can provide valid snapshots.
   683  
   684  #### Transition to Consensus
   685  
   686  Once the snapshots have all been restored, Tendermint gathers additional information necessary for
   687  bootstrapping the node (e.g. chain ID, consensus parameters, validator sets, and block headers)
   688  from the genesis file and light client RPC servers. It also fetches and records the `AppVersion`
   689  from the ABCI application.
   690  
   691  Once the state machine has been restored and Tendermint has gathered this additional
   692  information, it transitions to block sync (if enabled) to fetch any remaining blocks up the chain
   693  head, and then transitions to regular consensus operation. At this point the node operates like
   694  any other node, apart from having a truncated block history at the height of the restored snapshot.