mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-25 18:51:39 +00:00
route links to godoc rather than deprecated internal implementation, closes https://github.com/zramsay/tendermint/issues/1
This commit is contained in:
@ -8,36 +8,36 @@ But what exactly is stored in these blocks?
|
||||
|
||||
### Block
|
||||
|
||||
A [Block](/docs/specs/tendermint-types#Block) contains:
|
||||
A [Block](https://godoc.org/github.com/tendermint/tendermint/types#Block) contains:
|
||||
|
||||
* a [Header](#header) contains merkle hashes for various chain states
|
||||
* the [Data]((/docs/specs/tendermint-types#Data) is all transactions which are to be processed
|
||||
* the [Data](https://godoc.org/github.com/tendermint/tendermint/types#Data) is all transactions which are to be processed
|
||||
* the [LastCommit](#commit) > 2/3 signatures for the last block
|
||||
|
||||
The signatures returned along with block `H` are those validating block `H-1`.
|
||||
This can be a little confusing, but we must also consider that the
|
||||
[Header](/docs/specs/tendermint-types#Header) also contains the `LastCommitHash`.
|
||||
`Header` also contains the `LastCommitHash`.
|
||||
It would be impossible for a Header to include the commits that sign it, as it
|
||||
would cause an infinite loop here. But when we get block `H`, we find
|
||||
`Header.LastCommitHash`, which must match the hash of `LastCommit`.
|
||||
|
||||
### Header
|
||||
|
||||
The [Header](/docs/specs/tendermint-types#Header) contains lots of information (follow
|
||||
The [Header](https://godoc.org/github.com/tendermint/tendermint/types#Header) contains lots of information (follow
|
||||
link for up-to-date info). Notably, it maintains the `Height`, the `LastBlockID`
|
||||
(to make it a chain), and hashes of the data, the app state, and the validator set.
|
||||
This is important as the only item that is signed by the validators is the `Header`,
|
||||
and all other data must be validated against one of the merkle hashes in the `Header`.
|
||||
|
||||
The `DataHash` can provide a nice check on the [Data](/docs/specs/tendermint-types#Data)
|
||||
The `DataHash` can provide a nice check on the [Data](https://godoc.org/github.com/tendermint/tendermint/types#Data)
|
||||
returned in this same block. If you are subscribed to new blocks, via tendermint RPC, in order to display or process the new transactions
|
||||
you should at least validate that the `DataHash` is valid.
|
||||
If it is important to verify autheniticity, you must wait for the `LastCommit` from the next block to make sure the block header (including `DataHash`) was properly signed.
|
||||
|
||||
The `ValidatorHash` contains a hash of the current
|
||||
[Validators](/docs/specs/tendermint-types#Validator). Tracking all changes in the
|
||||
[Validators](https://godoc.org/github.com/tendermint/tendermint/types#Validator). Tracking all changes in the
|
||||
validator set is complex, but a client can quickly compare this hash
|
||||
with the [hash of the currently known validators](/docs/specs/tendermint-types#ValidatorSet.Hash)
|
||||
with the [hash of the currently known validators](https://godoc.org/github.com/tendermint/tendermint/types#ValidatorSet.Hash)
|
||||
to see if there have been changes.
|
||||
|
||||
The `AppHash` serves as the basis for validating any merkle proofs that come
|
||||
@ -58,29 +58,28 @@ immutability of the block chain, as the application only applies transactions
|
||||
|
||||
### Commit
|
||||
|
||||
The [Commit](/docs/specs/tendermint-types#Commit) contains a set of
|
||||
[Votes](/docs/specs/tendermint-types#Vote) that were made by the validator set to
|
||||
The [Commit](https://godoc.org/github.com/tendermint/tendermint/types#Commit) contains a set of
|
||||
[Votes](https://godoc.org/github.com/tendermint/tendermint/types#Vote) that were made by the validator set to
|
||||
reach consensus on this block. This is the key to the security in any PoS
|
||||
system, and actually no data that cannot be traced back to a block header
|
||||
with a valid set of Votes can be trusted. Thus, getting the Commit data
|
||||
and verifying the votes is extremely important.
|
||||
|
||||
As mentioned above, in order to find the `precommit votes` for block header `H`,
|
||||
we need to query block `H+1`. Then we need to check the votes, make sure they
|
||||
we need to query block `H+1`. Then we need to check the votes, make sure they
|
||||
really are for that block, and properly formatted. Much of this code is implemented
|
||||
in Go in the [light-client](https://github.com/tendermint/light-client) package,
|
||||
especially [Node.SignedHeader](https://github.com/tendermint/light-client/blob/develop/rpc/node.go#L117).
|
||||
in Go in the [light-client](https://github.com/tendermint/light-client) package.
|
||||
If you look at the code, you will notice that we need to provide the `chainID`
|
||||
of the blockchain in order to properly calculate the votes. This is to protect
|
||||
of the blockchain in order to properly calculate the votes. This is to protect
|
||||
anyone from swapping votes between chains to fake (or frame) a validator.
|
||||
Also note that this `chainID` is in the `genesis.json` from _Tendermint_,
|
||||
not the `genesis.json` from the basecoin app ([that is a different chainID...](https://github.com/tendermint/basecoin/issues/32)).
|
||||
|
||||
Once we have those votes,
|
||||
and we calculated the proper [sign bytes](/docs/specs/tendermint-types#Vote.WriteSignBytes)
|
||||
using the chainID and a [nice helper function](/docs/specs/tendermint-types#SignBytes),
|
||||
we can verify them. The light client is responsible for maintaining a set of
|
||||
validators that we trust. Each vote only stores the validators `Address`, as well
|
||||
and we calculated the proper [sign bytes](https://godoc.org/github.com/tendermint/tendermint/types#Vote.WriteSignBytes)
|
||||
using the chainID and a [nice helper function](https://godoc.org/github.com/tendermint/tendermint/types#SignBytes),
|
||||
we can verify them. The light client is responsible for maintaining a set of
|
||||
validators that we trust. Each vote only stores the validators `Address`, as well
|
||||
as the `Signature`. Assuming we have a local copy of the trusted validator set,
|
||||
we can look up the `Public Key` of the validator given its `Address`, then
|
||||
verify that the `Signature` matches the `SignBytes` and `Public Key`.
|
||||
@ -89,13 +88,6 @@ all these stringent requirements. If the total number of voting power for a sing
|
||||
than 2/3 of all voting power, then we can finally trust the
|
||||
block header, the AppHash, and the proof we got from the ABCI application.
|
||||
|
||||
To make this a bit more concrete, you can take a look at a
|
||||
[StaticCertifier](https://github.com/tendermint/light-client/blob/develop/rpc/certifier.go#L23)
|
||||
to see how this logic works, given a static set of validators. And you can see
|
||||
an example of how one can perform the entire chain of validation in the
|
||||
proxy server [proof call](https://github.com/tendermint/light-client/blob/develop/proxy/viewer.go#L61)
|
||||
or the [test code for auditing](https://github.com/tendermint/light-client/blob/develop/rpc/tests/node_test.go#L102).
|
||||
|
||||
#### Vote Sign Bytes
|
||||
The `sign-bytes` of a vote is produced by taking a [`stable-json`](https://github.com/substack/json-stable-stringify)-like deterministic JSON [`wire`](/docs/specs/wire-protocol) encoding of the vote (excluding the `Signature` field), and wrapping it with `{"chain_id":"my_chain","vote":...}`.
|
||||
|
||||
@ -107,15 +99,15 @@ For example, a precommit vote might have the following `sign-bytes`:
|
||||
|
||||
### Block Hash
|
||||
|
||||
The [block hash](/docs/specs/tendermint-types#Block.Hash) is the [Simple Tree hash](Merkle-Trees#simple-tree-with-dictionaries) of the fields of the block `Header` encoded as a list of `KVPair`s.
|
||||
The [block hash](https://godoc.org/github.com/tendermint/tendermint/types#Block.Hash) is the [Simple Tree hash](Merkle-Trees#simple-tree-with-dictionaries) of the fields of the block `Header` encoded as a list of `KVPair`s.
|
||||
|
||||
### 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.
|
||||
A transaction is any sequence of bytes. It is up to your [ABCI](https://github.com/tendermint/abci) application to accept or reject transactions.
|
||||
|
||||
### BlockID
|
||||
|
||||
Many of these data structures refer to the [BlockID](/docs/specs/tendermint-types#BlockID),
|
||||
Many of these data structures refer to the [BlockID](https://godoc.org/github.com/tendermint/tendermint/types#BlockID),
|
||||
which is the `BlockHash` (hash of the block header, also referred to by the next block)
|
||||
along with the `PartSetHeader`. The `PartSetHeader` is explained below and is used internally
|
||||
to orchestrate the p2p propogation. For clients, it is basically opaque bytes,
|
||||
@ -123,7 +115,7 @@ but they must match for all votes.
|
||||
|
||||
### PartSetHeader
|
||||
|
||||
The [PartSetHeader](/docs/specs/tendermint-types#PartSetHeader) contains the total number of pieces in a [PartSet](/docs/specs/tendermint-types#PartSet), and the Merkle root hash of those pieces.
|
||||
The [PartSetHeader](https://godoc.org/github.com/tendermint/tendermint/types#PartSetHeader) contains the total number of pieces in a [PartSet](https://godoc.org/github.com/tendermint/tendermint/types#PartSet), and the Merkle root hash of those pieces.
|
||||
|
||||
### PartSet
|
||||
|
||||
@ -137,7 +129,7 @@ PartSet was inspired by the LibSwift project.
|
||||
|
||||
Usage:
|
||||
|
||||
```Go
|
||||
```go
|
||||
data := RandBytes(2 << 20) // Something large
|
||||
|
||||
partSet := NewPartSetFromData(data)
|
||||
|
@ -7,7 +7,7 @@ _The draft 0.6 whitepaper is outdated. The new algorithm is detailed below. See
|
||||
- The consensus process in deciding the next block (at some _height_ `H`) is composed of one or many _rounds_.
|
||||
- `NewHeight`, `Propose`, `Prevote`, `Precommit`, and `Commit` represent state machine states of a round. (aka `RoundStep` or just "step").
|
||||
- A node is said to be _at_ a given height, round, and step, or at `(H,R,S)`, or at `(H,R)` in short to omit the step.
|
||||
- To _prevote_ or _precommit_ something means to broadcast a [prevote vote](/docs/specs/block-structure#vote) or [precommit vote](/docs/specs/block-structure#precommit-vote) for something.
|
||||
- To _prevote_ or _precommit_ something means to broadcast a [prevote vote](https://godoc.org/github.com/tendermint/tendermint/types#Vote) or [first precommit vote](https://godoc.org/github.com/tendermint/tendermint/types#FirstPrecommit) for something.
|
||||
- A vote _at_ `(H,R)` is a vote signed with the bytes for `H` and `R` included in its [`sign-bytes`](/docs/specs/block-structure#vote-sign-bytes).
|
||||
- _+2/3_ is short for "more than 2/3"
|
||||
- _1/3+_ is short for "1/3 or more"
|
||||
@ -20,11 +20,12 @@ the next block. Each round is composed of three _steps_ (`Propose`, `Prevote`, a
|
||||
`Precommit`), along with two special steps `Commit` and `NewHeight`.
|
||||
|
||||
In the optimal scenario, the order of steps is:
|
||||
|
||||
```
|
||||
NewHeight -> (Propose -> Prevote -> Precommit)+ -> Commit -> NewHeight ->...
|
||||
```
|
||||
|
||||
The sequence `(Propose -> Prevote -> Precommit)` is called a _round_. There may be more than one round required to commit a block at a given height. Examples for why more rounds may be required include:
|
||||
The sequence `(Propose -> Prevote -> Precommit)` is called a _round_. There may be more than one round required to commit a block at a given height. Examples for why more rounds may be required include:
|
||||
|
||||
- The designated proposer was not online.
|
||||
- The block proposed by the designated proposer was not valid.
|
||||
@ -35,6 +36,7 @@ The sequence `(Propose -> Prevote -> Precommit)` is called a _round_. There may
|
||||
Some of these problems are resolved by moving onto the next round & proposer. Others are resolved by increasing certain round timeout parameters over each successive round.
|
||||
|
||||
## State Machine Diagram
|
||||
|
||||
```
|
||||
+-------------------------------------+
|
||||
v |(Wait til `CommmitTime+timeoutCommit`)
|
||||
@ -58,14 +60,14 @@ Some of these problems are resolved by moving onto the next round & proposer. O
|
||||
|
||||
## Background Gossip
|
||||
|
||||
A node may not have a corresponding validator private key, but it nevertheless plays an active role in the consensus process by relaying relevant meta-data, proposals, blocks, and votes to its peers. A node that has the private keys of an active validator and is engaged in signing votes is called a _validator-node_. All nodes (not just validator-nodes) have an associated state (the current height, round, and step) and work to make progress.
|
||||
A node may not have a corresponding validator private key, but it nevertheless plays an active role in the consensus process by relaying relevant meta-data, proposals, blocks, and votes to its peers. A node that has the private keys of an active validator and is engaged in signing votes is called a _validator-node_. All nodes (not just validator-nodes) have an associated state (the current height, round, and step) and work to make progress.
|
||||
|
||||
Between two nodes there exists a `Connection`, and multiplexed on top of this connection are fairly throttled `Channel`s of information. An epidemic gossip protocol is implemented among some of these channels to bring peers up to speed on the most recent state of consensus. For example,
|
||||
Between two nodes there exists a `Connection`, and multiplexed on top of this connection are fairly throttled `Channel`s of information. An epidemic gossip protocol is implemented among some of these channels to bring peers up to speed on the most recent state of consensus. For example,
|
||||
|
||||
- Nodes gossip `PartSet` parts of the current round's proposer's proposed block. A LibSwift inspired algorithm is used to quickly broadcast blocks across the gossip network.
|
||||
- Nodes gossip prevote/precommit votes. A node NODE_A that is ahead of NODE_B can send NODE_B prevotes or precommits for NODE_B's current (or future) round to enable it to progress forward.
|
||||
- Nodes gossip prevotes for the proposed PoLC (proof-of-lock-change) round if one is proposed.
|
||||
- Nodes gossip to nodes lagging in blockchain height with block [commits](/docs/specs/block-structure/commit) for older blocks.
|
||||
- Nodes gossip to nodes lagging in blockchain height with block [commits](https://godoc.org/github.com/tendermint/tendermint/types#Commit) for older blocks.
|
||||
- Nodes opportunistically gossip `HasVote` messages to hint peers what votes it already has.
|
||||
- Nodes broadcast their current state to all neighboring peers. (but is not gossiped further)
|
||||
|
||||
@ -73,7 +75,7 @@ There's more, but let's not get ahead of ourselves here.
|
||||
|
||||
## Proposals
|
||||
|
||||
A proposal is signed and published by the designated proposer at each round. The proposer is chosen by a deterministic and non-choking round robin selection algorithm that selects proposers in proportion to their voting power. (see [implementation](https://github.com/tendermint/tendermint/blob/develop/types/validator_set.go#L49))
|
||||
A proposal is signed and published by the designated proposer at each round. The proposer is chosen by a deterministic and non-choking round robin selection algorithm that selects proposers in proportion to their voting power. (see [implementation](https://github.com/tendermint/tendermint/blob/develop/types/validator_set.go))
|
||||
|
||||
A proposal at `(H,R)` is composed of a block and an optional latest `PoLC-Round < R` which is included iff the proposer knows of one. This hints the network to allow nodes to unlock (when safe) to ensure the liveness property.
|
||||
|
||||
@ -187,9 +189,3 @@ there are no significant network partitions, to avoid situations where two
|
||||
conflicting reorg-proposals are signed.
|
||||
|
||||
Assuming that the external coordination medium and protocol is robust, it follows that forks are less of a concern than [censorship attacks](#censorship-attacks).
|
||||
|
||||
### Revisions
|
||||
|
||||
#### 0.6 -> 0.7 (current)
|
||||
1. Reduced the minimum number of signature steps from 3 to 2 by removing the "commit" vote and step.
|
||||
2. The protocol is more asynchronous: instead of each round taking a predetermined duration of time, each step of a round progresses after +2/3 of the step's votes are found and a timeout is reached, or immediately after +2/3 of matching votes (e.g. a PoLC for prevotes, or a commit for precommits).
|
||||
|
@ -8,6 +8,6 @@ In a proof of work blockchain, syncing with the chain is the same process as sta
|
||||
|
||||
To support faster syncing, tendermint offers a `fast-sync` mode, which is enabled by default, and can be toggled in the `config.toml` or via `--fast_sync=false`.
|
||||
|
||||
In this mode, the tendermint daemon will sync hundreds of times faster than if it used the real-time consensus process. Once caught up, the daemon will switch out of fast sync and into the normal consensus mode. After running for some time, the node is considered `caught up` if it has at least one peer and it's height is at least as high as the max reported peer height. See [the IsCaughtUp method](https://github.com/tendermint/tendermint/blob/master/blockchain/pool.go#L128).
|
||||
In this mode, the tendermint daemon will sync hundreds of times faster than if it used the real-time consensus process. Once caught up, the daemon will switch out of fast sync and into the normal consensus mode. After running for some time, the node is considered `caught up` if it has at least one peer and it's height is at least as high as the max reported peer height. See [the IsCaughtUp method](https://github.com/tendermint/tendermint/blob/b467515719e686e4678e6da4e102f32a491b85a0/blockchain/pool.go#L128).
|
||||
|
||||
If we're lagging sufficiently, we should go back to fast syncing, but this is an open issue: https://github.com/tendermint/tendermint/issues/129
|
||||
|
@ -16,7 +16,8 @@ NOTE: This does not (yet) specify the application state (e.g. initial distributi
|
||||
|
||||
### Sample genesis.json
|
||||
|
||||
This example is from the Basecoin mintnet example ([link to file](https://github.com/tendermint/mintnet/blob/master/examples/basecoin/mach1/core/genesis.json)).
|
||||
This example is from the Basecoin mintnet example:
|
||||
|
||||
```json
|
||||
{
|
||||
"genesis_time": "2016-02-05T06:02:31.526Z",
|
||||
|
@ -2,15 +2,12 @@
|
||||
|
||||
Light clients are an important part of the complete blockchain system for most applications. Tendermint provides unique speed and security properties for light client applications.
|
||||
|
||||
See our developing [light-client repository](github.com/tendermint/light-client).
|
||||
See our developing [light-client repository](https://github.com/tendermint/light-client).
|
||||
|
||||
## Overview
|
||||
|
||||
The objective of the light client protocol is to get a [commit](/docs/specs/validators#committing-a-block) for a recent [block hash](/docs/specs/block-structure#block-hash) where the commit includes a majority of signatures from the last known validator set. From there, all the application state is verifiable with [merkle proofs](/docs/specs/merkle-trees#iavl-tree).
|
||||
|
||||
### Syncing the Validator Set
|
||||
TODO
|
||||
|
||||
## Properties
|
||||
|
||||
- You get the full collateralized security benefits of Tendermint; No need to wait for confirmations.
|
||||
|
@ -1,4 +1,2 @@
|
||||
|
||||
|
||||
# types
|
||||
see the [godoc version](https://godoc.org/github.com/tendermint/tendermint/types)
|
||||
|
Reference in New Issue
Block a user