Merge branch 'develop' into zach/more-docs-fixes

This commit is contained in:
Zach
2018-06-25 10:27:33 -04:00
committed by GitHub
143 changed files with 10153 additions and 225 deletions

View File

@ -10,15 +10,14 @@ Make sure you [have Go installed](https://golang.org/doc/install).
Next, install the `abci-cli` tool and example applications:
go get -u github.com/tendermint/abci/cmd/abci-cli
go get github.com/tendermint/tendermint
If this fails, you may need to use [dep](https://github.com/golang/dep)
to get vendored dependencies:
cd $GOPATH/src/github.com/tendermint/abci
cd $GOPATH/src/github.com/tendermint/tendermint
make get_tools
make get_vendor_deps
make install
make install_abci
Now run `abci-cli` to see the list of commands:
@ -61,7 +60,7 @@ as `abci-cli` above. The kvstore just stores transactions in a merkle
tree.
Its code can be found
[here](https://github.com/tendermint/abci/blob/master/cmd/abci-cli/abci-cli.go)
[here](https://github.com/tendermint/tendermint/blob/develop/abci/cmd/abci-cli/abci-cli.go)
and looks like:
func cmdKVStore(cmd *cobra.Command, args []string) error {
@ -124,8 +123,8 @@ response.
The server may be generic for a particular language, and we provide a
[reference implementation in
Golang](https://github.com/tendermint/abci/tree/master/server). See the
[list of other ABCI implementations](./ecosystem.md) for servers in
Golang](https://github.com/tendermint/tendermint/tree/develop/abci/server). See the
[list of other ABCI implementations](./ecosystem.html) for servers in
other languages.
The handler is specific to the application, and may be arbitrary, so
@ -204,7 +203,7 @@ Now that we've got the hang of it, let's try another application, the
"counter" app.
Like the kvstore app, its code can be found
[here](https://github.com/tendermint/abci/blob/master/cmd/abci-cli/abci-cli.go)
[here](https://github.com/tendermint/tendermint/blob/master/abci/cmd/abci-cli/abci-cli.go)
and looks like:
func cmdCounter(cmd *cobra.Command, args []string) error {
@ -301,7 +300,7 @@ But the ultimate flexibility comes from being able to write the
application easily in any language.
We have implemented the counter in a number of languages [see the
example directory](https://github.com/tendermint/abci/tree/master/example).
example directory](https://github.com/tendermint/tendermint/tree/develop/abci/example).
To run the Node JS version, `cd` to `example/js` and run

324
docs/abci-spec.md Normal file
View File

@ -0,0 +1,324 @@
# ABCI Specification
## Message Types
ABCI requests/responses are defined as simple Protobuf messages in [this
schema file](https://github.com/tendermint/tendermint/blob/develop/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.
Some messages (`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
application-specific response `Code uint32`, where only `0` is reserved
for `OK`.
Some messages (`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.
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:
`BeginBlock, [DeliverTx], EndBlock, Commit`
where one `DeliverTx` is called for each transaction in the block.
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
### Echo
- **Request**:
- `Message (string)`: A string to echo back
- **Response**:
- `Message (string)`: The input string
- **Usage**:
- Echo a string to test an abci client/server implementation
### Flush
- **Usage**:
- Signals that messages queued on the client should be flushed to
the server. It is called periodically by the client
implementation to ensure asynchronous requests are actually
sent, and is called immediately to make a synchronous request,
which returns when the Flush response comes back.
### Info
- **Request**:
- `Version (string)`: The Tendermint version
- **Response**:
- `Data (string)`: Some arbitrary information
- `Version (Version)`: Version information
- `LastBlockHeight (int64)`: Latest block for which the app has
called Commit
- `LastBlockAppHash ([]byte)`: Latest result of Commit
- **Usage**:
- Return information about the application state.
- Used to sync Tendermint with the application during a handshake
that happens on startup.
- Tendermint expects `LastBlockAppHash` and `LastBlockHeight` to
be updated during `Commit`, ensuring that `Commit` is never
called twice for the same block height.
### SetOption
- **Request**:
- `Key (string)`: Key to set
- `Value (string)`: Value to set for key
- **Response**:
- `Code (uint32)`: Response code
- `Log (string)`: The output of the application's logger. May
be non-deterministic.
- `Info (string)`: Additional information. May
be non-deterministic.
- **Usage**:
- Set non-consensus critical application specific options.
- e.g. Key="min-fee", Value="100fermion" could set the minimum fee
required for CheckTx (but not DeliverTx - that would be
consensus critical).
### InitChain
- **Request**:
- `Validators ([]Validator)`: Initial genesis validators
- `AppStateBytes ([]byte)`: Serialized initial application state
- **Response**:
- `ConsensusParams (ConsensusParams)`: Initial
consensus-critical parameters.
- `Validators ([]Validator)`: Initial validator set.
- **Usage**:
- Called once upon genesis.
### Query
- **Request**:
- `Data ([]byte)`: Raw query bytes. Can be used with or in lieu
of Path.
- `Path (string)`: Path of request, like an HTTP GET path. Can be
used with or in liue of Data.
- Apps MUST interpret '/store' as a query by key on the
underlying store. The key SHOULD be specified in the Data field.
- Apps SHOULD allow queries over specific types like
'/accounts/...' or '/votes/...'
- `Height (int64)`: The block height for which you want the query
(default=0 returns data for the latest committed block). Note
that this is the height of the block containing the
application's Merkle root hash, which represents the state as it
was after committing the block at Height-1
- `Prove (bool)`: Return Merkle proof with response if possible
- **Response**:
- `Code (uint32)`: Response code.
- `Log (string)`: The output of the application's logger. May
be non-deterministic.
- `Info (string)`: Additional information. May
be non-deterministic.
- `Index (int64)`: The index of the key in the tree.
- `Key ([]byte)`: The key of the matching data.
- `Value ([]byte)`: The value of the matching data.
- `Proof ([]byte)`: Proof for the data, if requested.
- `Height (int64)`: The block height from which data was derived.
Note that this is the height of the block containing the
application's Merkle root hash, which represents the state as it
was after committing the block at Height-1
- **Usage**:
- Query for data from the application at current or past height.
- Optionally return Merkle proof.
### BeginBlock
- **Request**:
- `Hash ([]byte)`: The block's hash. This can be derived from the
block header.
- `Header (struct{})`: The block header
- `Validators ([]SigningValidator)`: List of validators in the current validator
set and whether or not they signed a vote in the LastCommit
- `ByzantineValidators ([]Evidence)`: List of evidence of
validators that acted maliciously
- **Response**:
- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing
- **Usage**:
- Signals the beginning of a new block. Called prior to
any DeliverTxs.
- The header is expected to at least contain the Height.
- The `Validators` and `ByzantineValidators` can be used to
determine rewards and punishments for the validators.
### CheckTx
- **Request**:
- `Tx ([]byte)`: The request transaction bytes
- **Response**:
- `Code (uint32)`: Response code
- `Data ([]byte)`: Result bytes, if any.
- `Log (string)`: The output of the application's logger. May
be non-deterministic.
- `Info (string)`: Additional information. May
be non-deterministic.
- `GasWanted (int64)`: Amount of gas request for transaction.
- `GasUsed (int64)`: Amount of gas consumed by transaction.
- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing
transactions (eg. by account).
- `Fee (cmn.KI64Pair)`: Fee paid for the transaction.
- **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`, where Tendermint ensures the mempool is locked and not
sending new `CheckTx`. After `Commit`, the mempool will rerun
CheckTx on all remaining transactions, throwing out any that are no
longer valid.
Keys and values in Tags must be UTF-8 encoded strings (e.g.
"account.owner": "Bob", "balance": "100.0", "date": "2018-01-02")
### DeliverTx
- **Request**:
- `Tx ([]byte)`: The request transaction bytes.
- **Response**:
- `Code (uint32)`: Response code.
- `Data ([]byte)`: Result bytes, if any.
- `Log (string)`: The output of the application's logger. May
be non-deterministic.
- `Info (string)`: Additional information. May
be non-deterministic.
- `GasWanted (int64)`: Amount of gas requested for transaction.
- `GasUsed (int64)`: Amount of gas consumed by transaction.
- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing
transactions (eg. by account).
- `Fee (cmn.KI64Pair)`: Fee paid for the transaction.
- **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")
### EndBlock
- **Request**:
- `Height (int64)`: Height of the block just executed.
- **Response**:
- `ValidatorUpdates ([]Validator)`: Changes to validator set (set
voting power to 0 to remove).
- `ConsensusParamUpdates (ConsensusParams)`: Changes to
consensus-critical time, size, and other parameters.
- `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 set and consensus params are updated with the result.
- Validator pubkeys are expected to be go-wire encoded.
### Commit
- **Response**:
- `Data ([]byte)`: The Merkle root hash
- **Usage**:
- Persist the application state.
- Return a Merkle root hash of the application state.
- It's critical that all application instances return the
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
### Header
- **Fields**:
- `ChainID (string)`: ID of the blockchain
- `Height (int64)`: Height of the block in the chain
- `Time (int64)`: Unix time of the block
- `NumTxs (int32)`: Number of transactions in the block
- `TotalTxs (int64)`: Total number of transactions in the blockchain until
now
- `LastBlockHash ([]byte)`: Hash of the previous (parent) block
- `ValidatorsHash ([]byte)`: Hash of the validator set for this block
- `AppHash ([]byte)`: Data returned by the last call to `Commit` - typically the
Merkle root of the application state after executing the previous block's
transactions
- `Proposer (Validator)`: Original proposer for the block
- **Usage**:
- Provided in RequestBeginBlock
- Provides important context about the current state of the blockchain -
especially height and time.
- Provides the proposer of the current block, for use in proposer-based
reward mechanisms.
### Validator
- **Fields**:
- `Address ([]byte)`: Address of the validator (hash of the public key)
- `PubKey (PubKey)`: Public key of the validator
- `Power (int64)`: Voting power of the validator
- **Usage**:
- Provides all identifying information about the validator
### SigningValidator
- **Fields**:
- `Validator (Validator)`: A validator
- `SignedLastBlock (bool)`: Indicated whether or not the validator signed
the last block
- **Usage**:
- Indicates whether a validator signed the last block, allowing for rewards
based on validator availability
### PubKey
- **Fields**:
- `Type (string)`: Type of the public key. A simple string like `"ed25519"`.
In the future, may indicate a serialization algorithm to parse the `Data`,
for instance `"amino"`.
- `Data ([]byte)`: Public key data. For a simple public key, it's just the
raw bytes. If the `Type` indicates an encoding algorithm, this is the
encoded public key.
- **Usage**:
- A generic and extensible typed public key
### Evidence
- **Fields**:
- `Type (string)`: Type of the evidence. A hierarchical path like
"duplicate/vote".
- `Validator (Validator`: The offending validator
- `Height (int64)`: Height when the offense was committed
- `Time (int64)`: Unix time of the block at height `Height`
- `TotalVotingPower (int64)`: Total voting power of the validator set at
height `Height`

View File

@ -47,4 +47,4 @@ See the following for more extensive documentation:
- [Tendermint RPC Docs](https://tendermint.github.io/slate/)
- [Tendermint in Production](https://github.com/tendermint/tendermint/pull/1618)
- [Tendermint Basics](https://tendermint.readthedocs.io/en/master/using-tendermint.html)
- [ABCI spec](https://github.com/tendermint/abci/blob/develop/specification.md)
- [ABCI spec](https://github.com/tendermint/tendermint/blob/develop/abci/docs/abci-spec.md)

View File

@ -49,7 +49,7 @@ The message protocol consists of pairs of requests and responses. Some
messages have no fields, while others may include byte-arrays, strings,
or integers. See the `message Request` and `message Response`
definitions in [the protobuf definition
file](https://github.com/tendermint/abci/blob/master/types/types.proto),
file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto),
and the [protobuf
documentation](https://developers.google.com/protocol-buffers/docs/overview)
for more details.
@ -72,9 +72,9 @@ Both can be tested using the `abci-cli` by setting the `--abci` flag
appropriately (ie. to `socket` or `grpc`).
See examples, in various stages of maintenance, in
[Go](https://github.com/tendermint/abci/tree/master/server),
[Go](https://github.com/tendermint/tendermint/tree/develop/abci/server),
[JavaScript](https://github.com/tendermint/js-abci),
[Python](https://github.com/tendermint/abci/tree/master/example/python3/abci),
[Python](https://github.com/tendermint/tendermint/tree/develop/abci/example/python3/abci),
[C++](https://github.com/mdyring/cpp-tmsp), and
[Java](https://github.com/jTendermint/jabci).
@ -84,7 +84,7 @@ If GRPC is available in your language, this is the easiest approach,
though it will have significant performance overhead.
To get started with GRPC, copy in the [protobuf
file](https://github.com/tendermint/abci/blob/master/types/types.proto)
file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto)
and compile it using the GRPC plugin for your language. For instance,
for golang, the command is `protoc --go_out=plugins=grpc:. types.proto`.
See the [grpc documentation for more details](http://www.grpc.io/docs/).
@ -99,14 +99,14 @@ performance, or otherwise enjoy programming, you may implement your own
ABCI server using the Tendermint Socket Protocol, known affectionately
as Teaspoon. The first step is still to auto-generate the relevant data
types and codec in your language using `protoc`. Messages coming over
the socket are Protobuf3 encoded, but additionally length-prefixed to
facilitate use as a streaming protocol. Protobuf3 doesn't have an
the socket are proto3 encoded, but additionally length-prefixed to
facilitate use as a streaming protocol. proto3 doesn't have an
official length-prefix standard, so we use our own. The first byte in
the prefix represents the length of the Big Endian encoded length. The
remaining bytes in the prefix are the Big Endian encoded length.
For example, if the Protobuf3 encoded ABCI message is 0xDEADBEEF (4
bytes), the length-prefixed message is 0x0104DEADBEEF. If the Protobuf3
For example, if the proto3 encoded ABCI message is 0xDEADBEEF (4
bytes), the length-prefixed message is 0x0104DEADBEEF. If the proto3
encoded ABCI message is 65535 bytes long, the length-prefixed message
would be like 0x02FFFF....
@ -125,12 +125,12 @@ received or a block is committed.
It is unlikely that you will need to implement a client. For details of
our client, see
[here](https://github.com/tendermint/abci/tree/master/client).
[here](https://github.com/tendermint/tendermint/tree/develop/abci/client).
Most of the examples below are from [kvstore
application](https://github.com/tendermint/abci/blob/master/example/kvstore/kvstore.go),
application](https://github.com/tendermint/tendermint/blob/develop/abci/example/kvstore/kvstore.go),
which is a part of the abci repo. [persistent_kvstore
application](https://github.com/tendermint/abci/blob/master/example/kvstore/persistent_kvstore.go)
application](https://github.com/tendermint/tendermint/blob/develop/abci/example/kvstore/persistent_kvstore.go)
is used to show `BeginBlock`, `EndBlock` and `InitChain` example
implementations.
@ -188,9 +188,9 @@ In Java:
ResponseCheckTx requestCheckTx(RequestCheckTx req) {
byte[] transaction = req.getTx().toByteArray();
// validate transaction
if (notValid) {
return ResponseCheckTx.newBuilder().setCode(CodeType.BadNonce).setLog("invalid tx").build();
} else {
@ -260,15 +260,15 @@ In Java:
*/
ResponseDeliverTx deliverTx(RequestDeliverTx request) {
byte[] transaction = request.getTx().toByteArray();
// validate your transaction
if (notValid) {
return ResponseDeliverTx.newBuilder().setCode(CodeType.BadNonce).setLog("transaction was invalid").build();
} else {
ResponseDeliverTx.newBuilder().setCode(CodeType.OK).build();
}
}
### Commit
@ -302,10 +302,10 @@ In go:
In Java:
ResponseCommit requestCommit(RequestCommit requestCommit) {
// update the internal app-state
byte[] newAppState = calculateAppState();
// and return it to the node
return ResponseCommit.newBuilder().setCode(CodeType.OK).setData(ByteString.copyFrom(newAppState)).build();
}
@ -326,7 +326,7 @@ In go:
func (app *PersistentKVStoreApplication) BeginBlock(params types.RequestBeginBlock) {
// update latest block info
app.blockHeader = params.Header
// reset valset changes
app.changes = make([]*types.Validator, 0)
}
@ -337,14 +337,14 @@ In Java:
* all types come from protobuf definition
*/
ResponseBeginBlock requestBeginBlock(RequestBeginBlock req) {
Header header = req.getHeader();
byte[] prevAppHash = header.getAppHash().toByteArray();
long prevHeight = header.getHeight();
long numTxs = header.getNumTxs();
// run your pre-block logic. Maybe prepare a state snapshot, message components, etc
return ResponseBeginBlock.newBuilder().build();
}
@ -377,10 +377,10 @@ In Java:
ResponseEndBlock requestEndBlock(RequestEndBlock req) {
final long currentHeight = req.getHeight();
final byte[] validatorPubKey = getValPubKey();
ResponseEndBlock.Builder builder = ResponseEndBlock.newBuilder();
builder.addDiffs(1, Types.Validator.newBuilder().setPower(10L).setPubKey(ByteString.copyFrom(validatorPubKey)).build());
return builder.build();
}
@ -437,25 +437,25 @@ In Java:
ResponseQuery requestQuery(RequestQuery req) {
final boolean isProveQuery = req.getProve();
final ResponseQuery.Builder responseBuilder = ResponseQuery.newBuilder();
if (isProveQuery) {
com.app.example.ProofResult proofResult = generateProof(req.getData().toByteArray());
final byte[] proofAsByteArray = proofResult.getAsByteArray();
responseBuilder.setProof(ByteString.copyFrom(proofAsByteArray));
responseBuilder.setKey(req.getData());
responseBuilder.setValue(ByteString.copyFrom(proofResult.getData()));
responseBuilder.setLog(result.getLogValue());
} else {
byte[] queryData = req.getData().toByteArray();
final com.app.example.QueryResult result = generateQueryResult(queryData);
responseBuilder.setIndex(result.getIndex());
responseBuilder.setValue(ByteString.copyFrom(result.getValue()));
responseBuilder.setLog(result.getLogValue());
}
return responseBuilder.build();
}
@ -515,13 +515,13 @@ In Java:
ResponseInitChain requestInitChain(RequestInitChain req) {
final int validatorsCount = req.getValidatorsCount();
final List<Types.Validator> validatorsList = req.getValidatorsList();
validatorsList.forEach((validator) -> {
long power = validator.getPower();
byte[] validatorPubKey = validator.getPubKey().toByteArray();
// do somehing for validator setup in app
});
return ResponseInitChain.newBuilder().build();
}

View File

@ -1,5 +1,22 @@
# Architecture Decision Records
# Architecture Decision Records (ADR)
This is a location to record all high-level architecture decisions in the tendermint project. Not the implementation details, but the reasoning that happened. This should be refered to for guidance of the "right way" to extend the application. And if we notice that the original decisions were lacking, we should have another open discussion, record the new decisions here, and then modify the code to match.
This is a location to record all high-level architecture decisions in the tendermint project.
Read up on the concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t).
You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t).
An ADR should provide:
- Context on the relevant goals and the current state
- Proposed changes to achieve the goals
- Summary of pros and cons
- References
- Changelog
Note the distinction between an ADR and a spec. The ADR provides the context, intuition, reasoning, and
justification for a change in architecture, or for the architecture of something
new. The spec is much more compressed and streamlined summary of everything as
it stands today.
If recorded decisions turned out to be lacking, convene a discussion, record the new decisions here, and then modify the code to match.
Note the context/background should be written in the present tense.

View File

@ -0,0 +1,273 @@
# ADR 009: ABCI UX Improvements
## Changelog
23-06-2018: Some minor fixes from review
07-06-2018: Some updates based on discussion with Jae
07-06-2018: Initial draft to match what was released in ABCI v0.11
## Context
The ABCI was first introduced in late 2015. It's purpose is to be:
- a generic interface between state machines and their replication engines
- agnostic to the language the state machine is written in
- agnostic to the replication engine that drives it
This means ABCI should provide an interface for both pluggable applications and
pluggable consensus engines.
To achieve this, it uses Protocol Buffers (proto3) for message types. The dominant
implementation is in Go.
After some recent discussions with the community on github, the following were
identified as pain points:
- Amino encoded types
- Managing validator sets
- Imports in the protobuf file
See the [references](#references) for more.
### Imports
The native proto library in Go generates inflexible and verbose code.
Many in the Go community have adopted a fork called
[gogoproto](https://github.com/gogo/protobuf) that provides a
variety of features aimed to improve the developer experience.
While `gogoproto` is nice, it creates an additional dependency, and compiling
the protobuf types for other languages has been reported to fail when `gogoproto` is used.
### Amino
Amino is an encoding protocol designed to improve over insufficiencies of protobuf.
It's goal is to be proto4.
Many people are frustrated by incompatibility with protobuf,
and with the requirement for Amino to be used at all within ABCI.
We intend to make Amino successful enough that we can eventually use it for ABCI
message types directly. By then it should be called proto4. In the meantime,
we want it to be easy to use.
### PubKey
PubKeys are encoded using Amino (and before that, go-wire).
Ideally, PubKeys are an interface type where we don't know all the
implementation types, so its unfitting to use `oneof` or `enum`.
### Addresses
The address for ED25519 pubkey is the RIPEMD160 of the Amino
encoded pubkey. This introduces an Amino dependency in the address generation,
a functionality that is widely required and should be easy to compute as
possible.
### Validators
To change the validator set, applications can return a list of validator updates
with ResponseEndBlock. In these updates, the public key *must* be included,
because Tendermint requires the public key to verify validator signatures. This
means ABCI developers have to work with PubKeys. That said, it would also be
convenient to work with address information, and for it to be simple to do so.
### AbsentValidators
Tendermint also provides a list of validators in BeginBlock who did not sign the
last block. This allows applications to reflect availability behaviour in the
application, for instance by punishing validators for not having votes included
in commits.
### InitChain
Tendermint passes in a list of validators here, and nothing else. It would
benefit the application to be able to control the initial validator set. For
instance the genesis file could include application-based information about the
initial validator set that the application could process to determine the
initial validator set. Additionally, InitChain would benefit from getting all
the genesis information.
### Header
ABCI provides the Header in RequestBeginBlock so the application can have
important information about the latest state of the blockchain.
## Decision
### Imports
Move away from gogoproto. In the short term, we will just maintain a second
protobuf file without the gogoproto annotations. In the medium term, we will
make copies of all the structs in Golang and shuttle back and forth. In the long
term, we will use Amino.
### Amino
To simplify ABCI application development in the short term,
Amino will be completely removed from the ABCI:
- It will not be required for PubKey encoding
- It will not be required for computing PubKey addresses
That said, we are working to make Amino a huge success, and to become proto4.
To facilitate adoption and cross-language compatibility in the near-term, Amino
v1 will:
- be fully compatible with the subset of proto3 that excludes `oneof`
- use the Amino prefix system to provide interface types, as opposed to `oneof`
style union types.
That said, an Amino v2 will be worked on to improve the performance of the
format and its useability in cryptographic applications.
### PubKey
Encoding schemes infect software. As a generic middleware, ABCI aims to have
some cross scheme compatibility. For this it has no choice but to include opaque
bytes from time to time. While we will not enforce Amino encoding for these
bytes yet, we need to provide a type system. The simplest way to do this is to
use a type string.
PubKey will now look like:
```
message PubKey {
string type
bytes data
}
```
where `type` can be:
- "ed225519", with `data = <raw 32-byte pubkey>`
- "secp256k1", with `data = <33-byte OpenSSL compressed pubkey>`
As we want to retain flexibility here, and since ideally, PubKey would be an
interface type, we do not use `enum` or `oneof`.
### Addresses
To simplify and improve computing addresses, we change it to the first 20-bytes of the SHA256
of the raw 32-byte public key.
We continue to use the Bitcoin address scheme for secp256k1 keys.
### Validators
Add a `bytes address` field:
```
message Validator {
bytes address
PubKey pub_key
int64 power
}
```
### RequestBeginBlock and AbsentValidators
To simplify this, RequestBeginBlock will include the complete validator set,
including the address, and voting power of each validator, along
with a boolean for whether or not they voted:
```
message RequestBeginBlock {
bytes hash
Header header
LastCommitInfo last_commit_info
repeated Evidence byzantine_validators
}
message LastCommitInfo {
int32 CommitRound
repeated SigningValidator validators
}
message SigningValidator {
Validator validator
bool signed_last_block
}
```
Note that in Validators in RequestBeginBlock, we DO NOT include public keys. Public keys are
larger than addresses and in the future, with quantum computers, will be much
larger. The overhead of passing them, especially during fast-sync, is
significant.
Additional, addresses are changing to be simpler to compute, further removing
the need to include pubkeys here.
In short, ABCI developers must be aware of both addresses and public keys.
### ResponseEndBlock
Since ResponseEndBlock includes Validator, it must now include their address.
### InitChain
Change RequestInitChain to give the app all the information from the genesis file:
```
message RequestInitChain {
int64 time
string chain_id
ConsensusParams consensus_params
repeated Validator validators
bytes app_state_bytes
}
```
Change ResponseInitChain to allow the app to specify the initial validator set
and consensus parameters.
```
message ResponseInitChain {
ConsensusParams consensus_params
repeated Validator validators
}
```
### Header
Now that Tendermint Amino will be compatible with proto3, the Header in ABCI
should exactly match the Tendermint header - they will then be encoded
identically in ABCI and in Tendermint Core.
## Status
Accepted.
## Consequences
### Positive
- Easier for developers to build on the ABCI
- ABCI and Tendermint headers are identically serialized
### Negative
- Maintenance overhead of alternative type encoding scheme
- Performance overhead of passing all validator info every block (at least its
only addresses, and not also pubkeys)
- Maintenance overhead of duplicate types
### Neutral
- ABCI developers must know about validator addresses
## References
- [ABCI v0.10.3 Specification (before this
proposal)](https://github.com/tendermint/abci/blob/v0.10.3/specification.rst)
- [ABCI v0.11.0 Specification (implementing first draft of this
proposal)](https://github.com/tendermint/abci/blob/v0.11.0/specification.md)
- [Ed25519 addresses](https://github.com/tendermint/go-crypto/issues/103)
- [InitChain contains the
Genesis](https://github.com/tendermint/abci/issues/216)
- [PubKeys](https://github.com/tendermint/tendermint/issues/1524)
- [Notes on
Header](https://github.com/tendermint/tendermint/issues/1605)
- [Gogoproto issues](https://github.com/tendermint/abci/issues/256)
- [Absent Validators](https://github.com/tendermint/abci/issues/231)

View File

@ -0,0 +1,78 @@
# ADR 010: Crypto Changes
## Context
Tendermint is a cryptographic protocol that uses and composes a variety of cryptographic primitives.
After nearly 4 years of development, Tendermint has recently undergone multiple security reviews to search for vulnerabilities and to assess the the use and composition of cryptographic primitives.
### Hash Functions
Tendermint uses RIPEMD160 universally as a hash function, most notably in its Merkle tree implementation.
RIPEMD160 was chosen because it provides the shortest fingerprint that is long enough to be considered secure (ie. birthday bound of 80-bits).
It was also developed in the open academic community, unlike NSA-designed algorithms like SHA256.
That said, the cryptographic community appears to unanimously agree on the security of SHA256. It has become a universal standard, especially now that SHA1 is broken, being required in TLS connections and having optimized support in hardware.
### Merkle Trees
Tendermint uses a simple Merkle tree to compute digests of large structures like transaction batches
and even blockchain headers. The Merkle tree length prefixes byte arrays before concatenating and hashing them.
It uses RIPEMD160.
### Addresses
ED25519 addresses are computed using the RIPEMD160 of the Amino encoding of the public key.
RIPEMD160 is generally considered an outdated hash function, and is much slower
than more modern functions like SHA256 or Blake2.
### Authenticated Encryption
Tendermint P2P connections use authenticated encryption to provide privacy and authentication in the communications.
This is done using the simple Station-to-Station protocol with the NaCL Ed25519 library.
While there have been no vulnerabilities found in the implementation, there are some concerns:
- NaCL uses Salsa20, a not-widely used and relatively out-dated stream cipher that has been obsoleted by ChaCha20
- Connections use RIPEMD160 to compute a value that is used for the encryption nonce with subtle requirements on how it's used
## Decision
### Hash Functions
Use the first 20-bytes of the SHA256 hash instead of RIPEMD160 for everything
### Merkle Trees
TODO
### Addresses
Compute ED25519 addresses as the first 20-bytes of the SHA256 of the raw 32-byte public key
### Authenticated Encryption
Make the following changes:
- Use xChaCha20 instead of xSalsa20 - https://github.com/tendermint/tendermint/issues/1124
- Use an HKDF instead of RIPEMD160 to compute nonces - https://github.com/tendermint/tendermint/issues/1165
## Status
## Consequences
### Positive
- More modern and standard cryptographic functions with wider adoption and hardware acceleration
### Negative
- Exact authenticated encryption construction isn't already provided in a well-used library
### Neutral
## References

View File

@ -197,10 +197,3 @@ copyfile('../DOCKER/README.md', tools_dir+'/docker.md')
urllib.urlretrieve(tools_repo+tools_branch+'/tm-bench/README.md', filename=tools_dir+'/benchmarking.md')
urllib.urlretrieve(tools_repo+tools_branch+'/tm-monitor/README.md', filename=tools_dir+'/monitoring.md')
#### abci spec #################################
abci_repo = "https://raw.githubusercontent.com/tendermint/abci/"
abci_branch = "develop"
urllib.urlretrieve(abci_repo+abci_branch+'/specification.md', filename='abci-spec.md')

View File

@ -1,5 +1,3 @@
# On Determinism
Arguably, the most difficult part of blockchain programming is determinism - that is, ensuring that sources of indeterminism do not creep into the design of such systems.
See [this issue](https://github.com/tendermint/abci/issues/56) for more information on the potential sources of indeterminism.

View File

@ -25,15 +25,11 @@ more info.
Then run
go get -u github.com/tendermint/abci/cmd/abci-cli
If there is an error, install and run the
[dep](https://github.com/golang/dep) tool to pin the dependencies:
cd $GOPATH/src/github.com/tendermint/abci
go get github.com/tendermint/tendermint
cd $GOPATH/src/github.com/tendermint/tendermint
make get_tools
make get_vendor_deps
make install
make install_abci
Now you should have the `abci-cli` installed; you'll see a couple of
commands (`counter` and `kvstore`) that are example applications written
@ -132,7 +128,7 @@ of the ASCII of `abcd`. You can verify this in a python 2 shell by
running `"61626364".decode('base64')` or in python 3 shell by running
`import codecs; codecs.decode("61626364", 'base64').decode('ascii')`.
Stay tuned for a future release that [makes this output more
human-readable](https://github.com/tendermint/abci/issues/32).
human-readable](https://github.com/tendermint/tendermint/issues/1794).
Now let's try setting a different key and value:

View File

@ -103,7 +103,7 @@ little overview what they do.
- `abci-client` As mentioned in [Application Development Guide](./app-development.md), Tendermint acts as an ABCI
client with respect to the application and maintains 3 connections:
mempool, consensus and query. The code used by Tendermint Core can
be found [here](https://github.com/tendermint/abci/tree/master/client).
be found [here](https://github.com/tendermint/tendermint/tree/develop/abci/client).
- `blockchain` Provides storage, pool (a group of peers), and reactor
for both storing and exchanging blocks between peers.
- `consensus` The heart of Tendermint core, which is the

View File

@ -119,9 +119,9 @@ consensus engine, and provides a particular application state.
## ABCI Overview
The [Application BlockChain Interface
(ABCI)](https://github.com/tendermint/abci) allows for Byzantine Fault
Tolerant replication of applications written in any programming
language.
(ABCI)](https://github.com/tendermint/tendermint/tree/develop/abci)
allows for Byzantine Fault Tolerant replication of applications
written in any programming language.
### Motivation
@ -159,7 +159,7 @@ Teaspoon).
[Tendermint Core](https://github.com/tendermint/tendermint) (the
"consensus engine") communicates with the application via a socket
protocol that satisfies the [ABCI](https://github.com/tendermint/abci).
protocol that satisfies the ABCI.
To draw an analogy, lets talk about a well-known cryptocurrency,
Bitcoin. Bitcoin is a cryptocurrency blockchain where each node
@ -187,7 +187,7 @@ core to the application. The application replies with corresponding
response messages.
The messages are specified here: [ABCI Message
Types](https://github.com/tendermint/abci#message-types).
Types](https://github.com/tendermint/tendermint/blob/develop/abci/README.md#message-types).
The **DeliverTx** message is the work horse of the application. Each
transaction in the blockchain is delivered with this message. The

View File

@ -8,28 +8,30 @@ This functionality is disabled by default.
To enable the Prometheus metrics, set `instrumentation.prometheus=true` if your
config file. Metrics will be served under `/metrics` on 26660 port by default.
Listen address can be changed in the config file (see
`prometheus_listen_addr`).
`instrumentation.prometheus_listen_addr`).
## List of available metrics
The following metrics are available:
```
| Name | Type | Since | Description |
| --------------------------------------- | ------- | --------- | ----------------------------------------------------------------------------- |
| consensus_height | Gauge | 0.20.1 | Height of the chain |
| consensus_validators | Gauge | 0.20.1 | Number of validators |
| consensus_validators_power | Gauge | 0.20.1 | Total voting power of all validators |
| consensus_missing_validators | Gauge | 0.20.1 | Number of validators who did not sign |
| consensus_missing_validators_power | Gauge | 0.20.1 | Total voting power of the missing validators |
| consensus_byzantine_validators | Gauge | 0.20.1 | Number of validators who tried to double sign |
| consensus_byzantine_validators_power | Gauge | 0.20.1 | Total voting power of the byzantine validators |
| consensus_block_interval_seconds | Histogram | 0.20.1 | Time between this and last block (Block.Header.Time) in seconds |
| consensus_rounds | Gauge | 0.20.1 | Number of rounds |
| consensus_num_txs | Gauge | 0.20.1 | Number of transactions |
| mempool_size | Gauge | 0.20.1 | Number of uncommitted transactions |
| consensus_total_txs | Gauge | 0.20.1 | Total number of transactions committed |
| consensus_block_size_bytes | Gauge | 0.20.1 | Block size in bytes |
| p2p_peers | Gauge | 0.20.1 | Number of peers node's connected to |
| consensus_height | Gauge | 0.21.0 | Height of the chain |
| consensus_validators | Gauge | 0.21.0 | Number of validators |
| consensus_validators_power | Gauge | 0.21.0 | Total voting power of all validators |
| consensus_missing_validators | Gauge | 0.21.0 | Number of validators who did not sign |
| consensus_missing_validators_power | Gauge | 0.21.0 | Total voting power of the missing validators |
| consensus_byzantine_validators | Gauge | 0.21.0 | Number of validators who tried to double sign |
| consensus_byzantine_validators_power | Gauge | 0.21.0 | Total voting power of the byzantine validators |
| consensus_block_interval_seconds | Histogram | 0.21.0 | Time between this and last block (Block.Header.Time) in seconds |
| consensus_rounds | Gauge | 0.21.0 | Number of rounds |
| consensus_num_txs | Gauge | 0.21.0 | Number of transactions |
| mempool_size | Gauge | 0.21.0 | Number of uncommitted transactions |
| consensus_total_txs | Gauge | 0.21.0 | Total number of transactions committed |
| consensus_block_size_bytes | Gauge | 0.21.0 | Block size in bytes |
| p2p_peers | Gauge | 0.21.0 | Number of peers node's connected to |
```
## Useful queries

View File

@ -78,6 +78,9 @@ We have a small tool, called `tm-monitor`, which outputs information from
the endpoints above plus some statistics. The tool can be found
[here](https://github.com/tendermint/tools/tree/master/tm-monitor).
Tendermint also can report and serve Prometheus metrics. See
[Metrics](./metrics.md).
## What happens when my app dies?
You are supposed to run Tendermint under a [process
@ -204,3 +207,37 @@ ranges](https://github.com/tendermint/tendermint/blob/27bd1deabe4ba6a2d9b463b8f3
This may not be the case for private networks, where your IP range is usually
strictly limited and private. If that case, you need to set `addr_book_strict`
to `false` (turn off).
- `rpc.max_open_connections`
By default, the number of simultaneous connections is limited because most OS
give you limited number of file descriptors.
If you want to accept greater number of connections, you will need to increase
these limits.
[Sysctls to tune the system to be able to open more connections](https://github.com/satori-com/tcpkali/blob/master/doc/tcpkali.man.md#sysctls-to-tune-the-system-to-be-able-to-open-more-connections)
...for N connections, such as 50k:
```
kern.maxfiles=10000+2*N # BSD
kern.maxfilesperproc=100+2*N # BSD
kern.ipc.maxsockets=10000+2*N # BSD
fs.file-max=10000+2*N # Linux
net.ipv4.tcp_max_orphans=N # Linux
# For load-generating clients.
net.ipv4.ip_local_port_range="10000 65535" # Linux.
net.inet.ip.portrange.first=10000 # BSD/Mac.
net.inet.ip.portrange.last=65535 # (Enough for N < 55535)
net.ipv4.tcp_tw_reuse=1 # Linux
net.inet.tcp.maxtcptw=2*N # BSD
# If using netfilter on Linux:
net.netfilter.nf_conntrack_max=N
echo $((N/8)) > /sys/module/nf_conntrack/parameters/hashsize
```
The similar option exists for limiting the number of gRPC connections -
`rpc.grpc_max_open_connections`.

View File

@ -2,8 +2,8 @@
## Amino
Tendermint uses the Protobuf3 derivative [Amino](https://github.com/tendermint/go-amino) for all data structures.
Think of Amino as an object-oriented Protobuf3 with native JSON support.
Tendermint uses the proto3 derivative [Amino](https://github.com/tendermint/go-amino) for all data structures.
Think of Amino as an object-oriented proto3 with native JSON support.
The goal of the Amino encoding protocol is to bring parity between application
logic objects and persistence objects.
@ -21,7 +21,7 @@ arbitrary object and return the Amino encoded bytes.
## Byte Arrays
The encoding of a byte array is simply the raw-bytes prefixed with the length of
the array as a `UVarint` (what Protobuf calls a `Varint`).
the array as a `UVarint` (what proto calls a `Varint`).
For details on varints, see the [protobuf
spec](https://developers.google.com/protocol-buffers/docs/encoding#varints).

View File

@ -4,14 +4,14 @@ ABCI is the interface between Tendermint (a state-machine replication engine)
and an application (the actual state machine).
The ABCI message types are defined in a [protobuf
file](https://github.com/tendermint/abci/blob/master/types/types.proto).
file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto).
For full details on the ABCI message types and protocol, see the [ABCI
specificaiton](https://github.com/tendermint/abci/blob/master/specification.rst).
specification](https://github.com/tendermint/tendermint/blob/develop/docs/abci-spec.md).
Be sure to read the specification if you're trying to build an ABCI app!
For additional details on server implementation, see the [ABCI
readme](https://github.com/tendermint/abci#implementation).
readme](https://github.com/tendermint/tendermint/blob/develop/abci/README.md).
Here we provide some more details around the use of ABCI by Tendermint and
clarify common "gotchas".

View File

@ -58,8 +58,7 @@ validators <https://godoc.org/github.com/tendermint/tendermint/types#ValidatorSe
to see if there have been changes.
The ``AppHash`` serves as the basis for validating any merkle proofs
that come from the `ABCI
application <https://github.com/tendermint/abci>`__. It represents the
that come from the ABCI application. It represents the
state of the actual application, rather that the state of the blockchain
itself. This means it's necessary in order to perform any business
logic, such as verifying an account balance.
@ -144,8 +143,7 @@ Transaction
~~~~~~~~~~~
A transaction is any sequence of bytes. It is up to your
`ABCI <https://github.com/tendermint/abci>`__ application to accept or
reject transactions.
ABCI application to accept or reject transactions.
BlockID
~~~~~~~

View File

@ -73,9 +73,23 @@ laddr = "tcp://0.0.0.0:26657"
# NOTE: This server only supports /broadcast_tx_commit
grpc_laddr = ""
# Maximum number of simultaneous connections.
# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections
# If you want to accept more significant number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
grpc_max_open_connections = 900
# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
unsafe = false
# Maximum number of simultaneous connections (including WebSocket).
# Does not include gRPC connections. See grpc_max_open_connections
# If you want to accept more significant number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
max_open_connections = 450
##### peer to peer configuration options #####
[p2p]

View File

@ -26,8 +26,7 @@ There are two ways to become validator.
1. They can be pre-established in the `genesis
state <./genesis.html>`__
2. The `ABCI app responds to the EndBlock
message <https://github.com/tendermint/abci>`__ with changes to the
2. The ABCI app responds to the EndBlock message with changes to the
existing validator set.
Committing a Block

View File

@ -45,8 +45,7 @@ blocks are produced regularly, even if there are no transactions. See
*No Empty Blocks*, below, to modify this setting.
Tendermint supports in-process versions of the `counter`, `kvstore` and
`nil` apps that ship as examples in the [ABCI
repository](https://github.com/tendermint/abci). It's easy to compile
`nil` apps that ship as examples with `abci-cli`. It's easy to compile
your own app in-process with Tendermint if it's written in Go. If your
app is not written in Go, simply run it in another process, and use the
`--proxy_app` flag to specify the address of the socket it is listening