docs/spec/abci: update spec
* better overview section * section on tags * remove notes about state/concurrency from CheckTx * incorporate feedback from #2249 * explain how validator set updates effect future blocks
This commit is contained in:
parent
20c55cffc4
commit
3fd54c5df5
|
@ -1,56 +1,82 @@
|
|||
# ABCI Specification
|
||||
# Application Blockchain Interface (ABCI)
|
||||
|
||||
## Message Types
|
||||
## Overview
|
||||
|
||||
ABCI requests/responses are defined as simple Protobuf messages in [this
|
||||
schema file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto).
|
||||
TendermintCore sends the requests, and the ABCI application sends the
|
||||
responses. Here, we provide an overview of the messages types and how
|
||||
they are used by Tendermint. Then we describe each request-response pair
|
||||
as a function with arguments and return values, and add some notes on
|
||||
usage.
|
||||
ABCI is the interface between Tendermint (a state-machine replication engine)
|
||||
and an application (the actual state machine). It consists of a set of
|
||||
*methods*, where each method has a corresponding `Request` and `Response` type.
|
||||
Tendermint calls the methods on the ABCI application by sending the `Request*`
|
||||
messages and receiving the `Response*` messages in return.
|
||||
|
||||
Some messages (`Echo, Info, InitChain, BeginBlock, EndBlock, Commit`),
|
||||
The ABCI message types are defined in a [protobuf
|
||||
file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto).
|
||||
|
||||
ABCI methods are split across 3 separate ABCI *connections*:
|
||||
|
||||
- `Consensus Connection: InitChain, BeginBlock, DeliverTx, EndBlock, Commit`
|
||||
- `Mempool Connection: CheckTx`
|
||||
- `Info Connection: Info, SetOption, Query`
|
||||
|
||||
The `Consensus Connection` is driven by a consensus protocol and is responsible
|
||||
for block exection.
|
||||
The `Mempool Connection` is for validating new transactions, before they're
|
||||
shared or included in a block.
|
||||
The `Info Connection` is for initialization and for queries from the user.
|
||||
|
||||
Additionally, there is a `Flush` method that is called on every connection,
|
||||
and an `Echo` method that is just for debugging.
|
||||
|
||||
|
||||
## Errors
|
||||
|
||||
Some methods (`Echo, Info, InitChain, BeginBlock, EndBlock, Commit`),
|
||||
don't return errors because an error would indicate a critical failure
|
||||
in the application and there's nothing Tendermint can do. The problem
|
||||
should be addressed and both Tendermint and the application restarted.
|
||||
All other messages (`SetOption, Query, CheckTx, DeliverTx`) return an
|
||||
All other methods (`SetOption, Query, CheckTx, DeliverTx`) return an
|
||||
application-specific response `Code uint32`, where only `0` is reserved
|
||||
for `OK`.
|
||||
|
||||
Some messages (`SetOption, Query, CheckTx, DeliverTx`) return
|
||||
## Tags
|
||||
|
||||
Some methods (`CheckTx, BeginBlock, DeliverTx, EndBlock`)
|
||||
include a `Tags` field in their `Response*`. Each tag is key-value pair denoting
|
||||
something about what happened during the methods execution.
|
||||
|
||||
Tags can be used to index transactions and blocks according to what happened
|
||||
during their execution.
|
||||
|
||||
Keys and values in tags must be UTF-8 encoded strings (e.g.
|
||||
"account.owner": "Bob", "balance": "100.0",
|
||||
"time": "2018-01-02T12:30:00Z")
|
||||
|
||||
## Determinism
|
||||
|
||||
Some methods (`SetOption, Query, CheckTx, DeliverTx`) return
|
||||
non-deterministic data in the form of `Info` and `Log`. The `Log` is
|
||||
intended for the literal output from the application's logger, while the
|
||||
`Info` is any additional info that should be returned.
|
||||
|
||||
All other fields in the `Response*` of all methods must be strictly deterministic.
|
||||
|
||||
For this reason, it is recommended that applications not be exposed to any
|
||||
external user or process except via the ABCI connections to a consensus engine
|
||||
like Tendermint Core.
|
||||
|
||||
## Block Execution
|
||||
|
||||
The first time a new blockchain is started, Tendermint calls
|
||||
`InitChain`. From then on, the Block Execution Sequence that causes the
|
||||
committed state to be updated is as follows:
|
||||
`InitChain`. From then on, the follow sequence of methods is executed for each
|
||||
block:
|
||||
|
||||
`BeginBlock, [DeliverTx], EndBlock, Commit`
|
||||
|
||||
where one `DeliverTx` is called for each transaction in the block.
|
||||
The result is an updated application state.
|
||||
Cryptographic commitments to the results of DeliverTx, EndBlock, and
|
||||
Commit are included in the header of the next block.
|
||||
|
||||
Tendermint opens three connections to the application to handle the
|
||||
different message types:
|
||||
|
||||
- `Consensus Connection - InitChain, BeginBlock, DeliverTx, EndBlock, Commit`
|
||||
- `Mempool Connection - CheckTx`
|
||||
- `Info Connection - Info, SetOption, Query`
|
||||
|
||||
The `Flush` message is used on every connection, and the `Echo` message
|
||||
is only used for debugging.
|
||||
|
||||
Note that messages may be sent concurrently across all connections -a
|
||||
typical application will thus maintain a distinct state for each
|
||||
connection. They may be referred to as the `DeliverTx state`, the
|
||||
`CheckTx state`, and the `Commit state` respectively.
|
||||
|
||||
See below for more details on the message types and how they are used.
|
||||
|
||||
## Request/Response Messages
|
||||
## Messages
|
||||
|
||||
### Echo
|
||||
|
||||
|
@ -198,26 +224,17 @@ See below for more details on the message types and how they are used.
|
|||
- `GasUsed (int64)`: Amount of gas consumed by transaction.
|
||||
- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing
|
||||
transactions (eg. by account).
|
||||
- **Usage**: Validate a mempool transaction, prior to broadcasting
|
||||
or proposing. CheckTx should perform stateful but light-weight
|
||||
checks of the validity of the transaction (like checking signatures
|
||||
and account balances), but need not execute in full (like running a
|
||||
smart contract).
|
||||
|
||||
Tendermint runs CheckTx and DeliverTx concurrently with eachother,
|
||||
though on distinct ABCI connections - the mempool connection and the
|
||||
consensus connection, respectively.
|
||||
|
||||
The application should maintain a separate state to support CheckTx.
|
||||
This state can be reset to the latest committed state during
|
||||
`Commit`. Before calling Commit, Tendermint will lock and flush the mempool,
|
||||
ensuring that all existing CheckTx are responded to and no new ones can
|
||||
begin. After `Commit`, the mempool will rerun
|
||||
CheckTx for all remaining transactions, throwing out any that are no longer valid.
|
||||
Then the mempool will unlock and start sending CheckTx again.
|
||||
|
||||
Keys and values in Tags must be UTF-8 encoded strings (e.g.
|
||||
"account.owner": "Bob", "balance": "100.0", "date": "2018-01-02")
|
||||
- **Usage**:
|
||||
- Technically optional - not involved in processing blocks.
|
||||
- Guardian of the mempool: every node runs CheckTx before letting a
|
||||
transaction into its local mempool.
|
||||
- The transaction may come from an external user or another node
|
||||
- CheckTx need not execute the transaction in full, but rather a light-weight
|
||||
yet stateful validation, like checking signatures and account balances, but
|
||||
not running code in a virtual machine.
|
||||
- Transactions where `ResponseCheckTx.Code != 0` will be rejected - they will not be broadcast to
|
||||
other nodes or included in a proposal block.
|
||||
- Tendermint attributes no other value to the response code
|
||||
|
||||
### DeliverTx
|
||||
|
||||
|
@ -235,11 +252,9 @@ See below for more details on the message types and how they are used.
|
|||
- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing
|
||||
transactions (eg. by account).
|
||||
- **Usage**:
|
||||
- Deliver a transaction to be executed in full by the application.
|
||||
If the transaction is valid, returns CodeType.OK.
|
||||
- Keys and values in Tags must be UTF-8 encoded strings (e.g.
|
||||
"account.owner": "Bob", "balance": "100.0",
|
||||
"time": "2018-01-02T12:30:00Z")
|
||||
- The workhorse of the application - non-optional.
|
||||
- Execute the transaction in full.
|
||||
- `ResponseDeliverTx.Code == 0` only if the transaction is fully valid.
|
||||
|
||||
### EndBlock
|
||||
|
||||
|
@ -253,12 +268,13 @@ See below for more details on the message types and how they are used.
|
|||
- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing
|
||||
- **Usage**:
|
||||
- Signals the end of a block.
|
||||
- Called prior to each Commit, after all transactions.
|
||||
- Validator updates returned for block H:
|
||||
- apply to the NextValidatorsHash of block H+1
|
||||
- apply to the ValidatorsHash (and thus the validator set) for block H+2
|
||||
- apply to the RequestBeginBlock.LastCommitInfo (ie. the last validator set) for block H+3
|
||||
- Consensus params returned for block H apply for block H+1
|
||||
- Called after all transactions, prior to each Commit.
|
||||
- Validator updates returned by block `H` impact blocks `H+1`, `H+2`, and
|
||||
`H+3`, but only effects changes on the validator set of `H+2`:
|
||||
- `H+1`: NextValidatorsHash
|
||||
- `H+2`: ValidatorsHash (and thus the validator set)
|
||||
- `H+3`: LastCommitInfo (ie. the last validator set)
|
||||
- Consensus params returned for block `H` apply for block `H+1`
|
||||
|
||||
### Commit
|
||||
|
||||
|
@ -271,7 +287,7 @@ See below for more details on the message types and how they are used.
|
|||
same hash. If not, they will not be able to agree on the next
|
||||
block, because the hash is included in the next block!
|
||||
|
||||
## Data Messages
|
||||
## Data Types
|
||||
|
||||
### Header
|
||||
|
||||
|
|
Loading…
Reference in New Issue