`Hydrachain <https://github.com/HydraChain/hydrachain>`__ is a Pyethereum adapted to a non-BFT consensus algorithm modelled on Tendermint.
`Juno <https://github.com/kadena-io/juno>`__ is written in Haskell by Kadena and is a variant of Tangaroa, a BFT version of Raft.
`HoneyBadgerBFT <https://github.com/amiller/HoneyBadgerBFT>`__ is written in Python by Andrew Miller and is a fully asynchronous and highly optimized BFT using secret-sharing.
The `Application BlockChain Interface (ABCI) <https://github.com/tendermint/abci>`__ allows for Byzantine Fault Tolerant replication of applications written in any programming language.
Thus far, all blockchains "stacks" (such as `Bitcoin <https://github.com/bitcoin/bitcoin>`__) have had a monolithic design. That is, each blockchain stack is a single program that handles all the concerns of a decentralized ledger; this includes P2P connectivity, the "mempool" broadcasting of transactions, consensus on the most recent block, account balances, Turing-complete contracts, user-level permissions, etc.
Using a monolithic architecture is typically bad practice in computer science.
It makes it difficult to reuse components of the code, and attempts to do so result in complex maintanence procedures for forks of the codebase.
This is especially true when the codebase is not modular in design and suffers from "spaghetti code".
Another problem with monolithic design is that it limits you to the language of the blockchain stack (or vice versa). In the case of Ethereum which supports a Turing-complete bytecode virtual-machine, it limits you to languages that compile down to that bytecode; today, those are Serpent and Solidity.
In contrast, our approach is to decouple the consensus engine and P2P layers from the details of the application state of the particular blockchain application.
We do this by abstracting away the details of the application to an interface, which is implemented as a socket protocol.
Thus we have an interface, the Application BlockChain Interface (ABCI), and its primary implementation, the Tendermint Socket Protocol (TSP, or Teaspoon).
To draw an analogy, lets talk about a well-known cryptocurrency, Bitcoin. Bitcoin is a cryptocurrency blockchain where each node maintains a fully audited Unspent Transaction Output (UTXO) database. If one wanted to create a Bitcoin-like system on top of ABCI, Tendermint Core would be responsible for
- Establishing a canonical/immutable order of transactions (the blockchain)
The application will be responsible for
- Maintaining the UTXO database
- Validating cryptographic signatures of transactions
- Preventing transactions from spending non-existent transactions
- Allowing clients to query the UTXO database.
Tendermint is able to decompose the blockchain design by offering a very simple API (ie. the ABCI) between the application process and consensus process.
The ABCI consists of 3 primary message types that get delivered from the core to the application. The application replies with corresponding response messages.
The `DeliverTx` message is the work horse of the application. Each transaction in the blockchain is delivered with this message. The application needs to validate each transaction received with the `DeliverTx` message against the current state, application protocol, and the cryptographic credentials of the transaction. A validated transaction then needs to update the application state — by binding a value into a key values store, or by updating the UTXO database, for instance.
The `CheckTx` message is similar to `DeliverTx`, but it's only for validating transactions. Tendermint Core's mempool first checks the validity of a transaction with `CheckTx`, and only relays valid transactions to its peers. For instance, an application may check an incrementing sequence number in the transaction and return an error upon `CheckTx` if the sequence number is old. Alternatively, they might use a capabilities based system that requires capabilities to be renewed with every transaction.
The `Commit` message is used to compute a cryptographic commitment to the current application state, to be placed into the next block header. This has some handy properties. Inconsistencies in updating that state will now appear as blockchain forks which catches a whole class of programming errors. This also simplifies the development of secure lightweight clients, as Merkle-hash proofs can be verified by checking against the block hash, and that the block hash is signed by a quorum.
There can be multiple ABCI socket connections to an application. Tendermint Core creates three ABCI connections to the application; one for the validation of transactions when broadcasting in the mempool, one for the consensus engine to run block proposals, and one more for querying the application state.
It's probably evident that applications designers need to very carefully design their message handlers to create a blockchain that does anything useful but this architecture provides a place to start. The diagram below illustrates the flow of messages via ABCI.
The logic for blockchain transaction processing must be deterministic. If the application logic weren't deterministic, consensus would not be reached among the Tendermint Core replica nodes.
Solidity on Ethereum is a great language of choice for blockchain applications because, among other reasons, it is a completely deterministic programming language. However, it's also possible to create deterministic applications using existing popular languages like Java, C++, Python, or Go. Game programmers and blockchain developers are already familiar with creating deterministic programs by avoiding sources of non-determinism such as:
* language features that are random (e.g. map iteration in Go)
While programmers can avoid non-determinism by being careful, it is also possible to create a special linter or static analyzer for each language to check for determinism. In the future we may work with partners to create such tools.
Consensus Overview
------------------
Tendermint is an easy-to-understand, mostly asynchronous, BFT consensus protocol.
The protocol follows a simple state machine that looks like this:
Participants in the protocol are called "validators";
they take turns proposing blocks of transactions and voting on them.
Blocks are committed in a chain, with one block at each "height".
A block may fail to be committed, in which case the protocol moves to the next "round",
and a new validator gets to propose a block for that height.
Two stages of voting are required to successfully commit a block;
we call them "pre-vote" and "pre-commit".
A block is committed when more than 2/3 of validators pre-commit for the same block in the same round.
There is a picture of a couple doing the polka because validators are doing something like a polka dance.
When more than two-thirds of the validators pre-vote for the same block, we call that a "polka".
Every pre-commit must be justified by a polka in the same round.
Validators may fail to commit a block for a number of reasons;
the current proposer may be offline, or the network may be slow.
Tendermint allows them to establish that a validator should be skipped.
Validators wait a small amount of time to receive a complete proposal block from the proposer before voting to move to the next round.
This reliance on a timeout is what makes Tendermint a weakly synchronous protocol, rather than an asynchronous one.
However, the rest of the protocol is asynchronous, and validators only make progress after hearing from more than two-thirds of the validator set.
A simplifying element of Tendermint is that it uses the same mechanism to commit a block as it does to skip to the next round.
Assuming less than one-third of the validators are Byzantine, Tendermint guarantees that safety will never be violated - that is, validators will never commit conflicting blocks at the same height.
To do this it introduces a few "locking" rules which modulate which paths can be followed in the flow diagram.
Once a validator precommits a block, it is "locked" on that block.
Then,
1) it must prevote for the block it is locked on
2) it can only unlock, and precommit for a new block, if there is a polka for that block in a later round
Stake
-----
In many systems, not all validators will have the same "weight" in the consensus protocol.
Thus, we are not so much interested in one-third or two-thirds of the validators, but in those proportions of the total voting power,
which may not be uniformly distributed across individual validators.
Since Tendermint can replicate arbitrary applications, it is possible to define a currency, and denominate the voting power in that currency.
When voting power is denominated in a native currency, the system is often referred to as Proof-of-Stake.
Validators can be forced, by logic in the application,
to "bond" their currency holdings in a security deposit that can be destroyed if they're found to misbehave in the consensus protocol.
This adds an economic element to the security of the protocol, allowing one to quantify the cost of violating the assumption that less than one-third of voting power is Byzantine.
The `Cosmos Network <http://cosmos.network>`__ is designed to use this Proof-of-Stake mechanism across an array of cryptocurrencies implemented as ABCI applications.
The following diagram is Tendermint in a (technical) nutshell. `See here for high resolution version <https://github.com/mobfoundry/hackatom/blob/master/tminfo.pdf>`__.