tendermint/docs/specification/new-spec/blockchain.md

425 lines
11 KiB
Markdown
Raw Normal View History

2017-12-21 19:18:23 -08:00
# Tendermint Blockchain
Here we describe the data structures in the Tendermint blockchain and the rules for validating them.
2018-01-03 01:46:43 -08:00
## Data Structures
2017-12-21 19:18:23 -08:00
The Tendermint blockchains consists of a short list of basic data types:
2018-01-24 18:11:07 -08:00
2018-01-26 14:26:11 -08:00
- `Block`
2018-01-24 18:11:07 -08:00
- `Header`
- `Vote`
- `BlockID`
- `Signature`
- `Evidence`
2017-12-21 19:18:23 -08:00
## Block
2017-12-26 12:30:27 -08:00
A block consists of a header, a list of transactions, a list of votes (the commit),
2018-01-21 15:19:38 -08:00
and a list of evidence of malfeasance (ie. signing conflicting votes).
2017-12-21 19:18:23 -08:00
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
type Block struct {
Header Header
Txs [][]byte
LastCommit []Vote
Evidence []Evidence
}
```
## Header
A block header contains metadata about the block and about the consensus, as well as commitments to
the data in the current block, the previous block, and the results returned by the application:
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
type Header struct {
// block metadata
Version string // Version string
ChainID string // ID of the chain
2018-01-24 18:11:07 -08:00
Height int64 // Current block height
2017-12-21 19:18:23 -08:00
Time int64 // UNIX time, in millisconds
// current block
NumTxs int64 // Number of txs in this block
TxHash []byte // SimpleMerkle of the block.Txs
LastCommitHash []byte // SimpleMerkle of the block.LastCommit
// previous block
TotalTxs int64 // prevBlock.TotalTxs + block.NumTxs
LastBlockID BlockID // BlockID of prevBlock
// application
ResultsHash []byte // SimpleMerkle of []abci.Result from prevBlock
AppHash []byte // Arbitrary state digest
ValidatorsHash []byte // SimpleMerkle of the ValidatorSet
ConsensusParamsHash []byte // SimpleMerkle of the ConsensusParams
// consensus
Proposer []byte // Address of the block proposer
EvidenceHash []byte // SimpleMerkle of []Evidence
}
```
2018-01-24 18:11:07 -08:00
Further details on each of these fields is described below.
2017-12-26 12:30:27 -08:00
2017-12-21 19:18:23 -08:00
## BlockID
The `BlockID` contains two distinct Merkle roots of the block.
The first, used as the block's main hash, is the Merkle root
of all the fields in the header. The second, used for secure gossipping of
the block during consensus, is the Merkle root of the complete serialized block
2017-12-26 12:30:27 -08:00
cut into parts. The `BlockID` includes these two hashes, as well as the number of
parts.
2017-12-21 19:18:23 -08:00
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
type BlockID struct {
2017-12-26 15:43:03 -08:00
Hash []byte
Parts PartsHeader
}
type PartsHeader struct {
Hash []byte
Total int32
2017-12-21 19:18:23 -08:00
}
```
## Vote
A vote is a signed message from a validator for a particular block.
The vote includes information about the validator signing it.
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
type Vote struct {
Timestamp int64
Address []byte
Index int
Height int64
Round int
Type int8
BlockID BlockID
Signature Signature
}
```
2017-12-26 12:30:27 -08:00
There are two types of votes:
2018-01-24 18:11:07 -08:00
a *prevote* has `vote.Type == 1` and
a *precommit* has `vote.Type == 2`.
2017-12-26 12:30:27 -08:00
2017-12-21 19:18:23 -08:00
## Signature
Tendermint allows for multiple signature schemes to be used by prepending a single type-byte
2017-12-26 12:30:27 -08:00
to the signature bytes. Different signatures may also come with fixed or variable lengths.
Currently, Tendermint supports Ed25519 and Secp256k1.
### ED25519
An ED25519 signature has `Type == 0x1`. It looks like:
2017-12-21 19:18:23 -08:00
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
// Implements Signature
type Ed25519Signature struct {
Type int8 = 0x1
Signature [64]byte
}
2017-12-26 12:30:27 -08:00
```
where `Signature` is the 64 byte signature.
### Secp256k1
2017-12-21 19:18:23 -08:00
2017-12-26 12:30:27 -08:00
A `Secp256k1` signature has `Type == 0x2`. It looks like:
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
// Implements Signature
type Secp256k1Signature struct {
Type int8 = 0x2
Signature []byte
}
```
2017-12-26 12:30:27 -08:00
where `Signature` is the DER encoded signature, ie:
2018-01-03 01:46:43 -08:00
```hex
2017-12-26 12:30:27 -08:00
0x30 <length of whole message> <0x02> <length of R> <R> 0x2 <length of S> <S>.
```
2017-12-26 13:33:42 -08:00
## Evidence
TODO
2018-01-03 01:46:43 -08:00
## Validation
2017-12-21 19:18:23 -08:00
2017-12-26 15:43:03 -08:00
Here we describe the validation rules for every element in a block.
2017-12-21 19:18:23 -08:00
Blocks which do not satisfy these rules are considered invalid.
We abuse notation by using something that looks like Go, supplemented with English.
2017-12-26 12:30:27 -08:00
A statement such as `x == y` is an assertion - if it fails, the item is invalid.
We refer to certain globally available objects:
`block` is the block under consideration,
`prevBlock` is the `block` at the previous height,
2017-12-26 15:43:03 -08:00
and `state` keeps track of the validator set, the consensus parameters
and other results from the application.
Elements of an object are accessed as expected,
ie. `block.Header`. See [here](state.md) for the definition of `state`.
2017-12-21 19:18:23 -08:00
2018-01-03 01:46:43 -08:00
### Header
2017-12-21 19:18:23 -08:00
A Header is valid if its corresponding fields are valid.
### Version
Arbitrary string.
### ChainID
Arbitrary constant string.
### Height
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
block.Header.Height > 0
block.Header.Height == prevBlock.Header.Height + 1
```
2017-12-26 13:33:42 -08:00
The height is an incrementing integer. The first block has `block.Header.Height == 1`.
2017-12-21 19:18:23 -08:00
### Time
The median of the timestamps of the valid votes in the block.LastCommit.
2017-12-26 15:43:03 -08:00
Corresponds to the number of nanoseconds, with millisecond resolution, since January 1, 1970.
2017-12-27 12:14:49 -08:00
2018-01-24 18:11:07 -08:00
Note: the timestamp of a vote must be greater by at least one millisecond than that of the
2017-12-27 12:14:49 -08:00
block being voted on.
2017-12-21 19:18:23 -08:00
### NumTxs
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
block.Header.NumTxs == len(block.Txs)
```
Number of transactions included in the block.
### TxHash
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
block.Header.TxHash == SimpleMerkleRoot(block.Txs)
```
Simple Merkle root of the transactions in the block.
### LastCommitHash
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
block.Header.LastCommitHash == SimpleMerkleRoot(block.LastCommit)
```
Simple Merkle root of the votes included in the block.
These are the votes that committed the previous block.
2017-12-26 13:33:42 -08:00
The first block has `block.Header.LastCommitHash == []byte{}`
2017-12-21 19:18:23 -08:00
### TotalTxs
2018-01-03 01:46:43 -08:00
```go
2017-12-26 13:33:42 -08:00
block.Header.TotalTxs == prevBlock.Header.TotalTxs + block.Header.NumTxs
2017-12-21 19:18:23 -08:00
```
The cumulative sum of all transactions included in this blockchain.
2017-12-26 13:33:42 -08:00
The first block has `block.Header.TotalTxs = block.Header.NumberTxs`.
2017-12-21 19:18:23 -08:00
### LastBlockID
2018-01-26 14:26:11 -08:00
LastBlockID is the previous block's BlockID:
2018-01-24 18:11:07 -08:00
2018-01-03 01:46:43 -08:00
```go
2017-12-27 12:14:49 -08:00
prevBlockParts := MakeParts(prevBlock, state.LastConsensusParams.BlockGossip.BlockPartSize)
block.Header.LastBlockID == BlockID {
Hash: SimpleMerkleRoot(prevBlock.Header),
2017-12-26 15:43:03 -08:00
PartsHeader{
2017-12-27 12:14:49 -08:00
Hash: SimpleMerkleRoot(prevBlockParts),
Total: len(prevBlockParts),
2017-12-26 15:43:03 -08:00
},
2017-12-21 19:18:23 -08:00
}
```
2018-01-24 18:11:07 -08:00
Note: it depends on the ConsensusParams,
2017-12-21 19:18:23 -08:00
which are held in the `state` and may be updated by the application.
2017-12-26 13:33:42 -08:00
The first block has `block.Header.LastBlockID == BlockID{}`.
2017-12-21 19:18:23 -08:00
### ResultsHash
2018-01-03 01:46:43 -08:00
```go
2017-12-26 15:43:03 -08:00
block.ResultsHash == SimpleMerkleRoot(state.LastResults)
2017-12-21 19:18:23 -08:00
```
Simple Merkle root of the results of the transactions in the previous block.
2017-12-26 13:33:42 -08:00
The first block has `block.Header.ResultsHash == []byte{}`.
2017-12-21 19:18:23 -08:00
### AppHash
2018-01-03 01:46:43 -08:00
```go
2017-12-26 15:43:03 -08:00
block.AppHash == state.AppHash
2017-12-21 19:18:23 -08:00
```
Arbitrary byte array returned by the application after executing and commiting the previous block.
2017-12-26 13:33:42 -08:00
The first block has `block.Header.AppHash == []byte{}`.
2017-12-21 19:18:23 -08:00
### ValidatorsHash
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
block.ValidatorsHash == SimpleMerkleRoot(state.Validators)
```
Simple Merkle root of the current validator set that is committing the block.
This can be used to validate the `LastCommit` included in the next block.
2017-12-26 13:33:42 -08:00
May be updated by the application.
2017-12-21 19:18:23 -08:00
### ConsensusParamsHash
2018-01-03 01:46:43 -08:00
```go
2017-12-27 12:14:49 -08:00
block.ConsensusParamsHash == SimpleMerkleRoot(state.ConsensusParams)
2017-12-21 19:18:23 -08:00
```
Simple Merkle root of the consensus parameters.
May be updated by the application.
### Proposer
2018-01-03 01:46:43 -08:00
```go
2017-12-26 13:33:42 -08:00
block.Header.Proposer in state.Validators
```
2017-12-26 15:43:03 -08:00
Original proposer of the block. Must be a current validator.
2017-12-21 19:18:23 -08:00
2018-01-26 14:26:11 -08:00
NOTE: we also need to track the round.
2017-12-21 19:18:23 -08:00
2018-01-26 14:26:11 -08:00
## EvidenceHash
2017-12-21 19:18:23 -08:00
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
block.EvidenceHash == SimpleMerkleRoot(block.Evidence)
```
Simple Merkle root of the evidence of Byzantine behaviour included in this block.
## Txs
Arbitrary length array of arbitrary length byte-arrays.
## LastCommit
2017-12-26 12:30:27 -08:00
The first height is an exception - it requires the LastCommit to be empty:
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
if block.Header.Height == 1 {
len(b.LastCommit) == 0
}
```
Otherwise, we require:
2018-01-03 01:46:43 -08:00
```go
2017-12-21 19:18:23 -08:00
len(block.LastCommit) == len(state.LastValidators)
talliedVotingPower := 0
for i, vote := range block.LastCommit{
if vote == nil{
continue
}
vote.Type == 2
vote.Height == block.LastCommit.Height()
vote.Round == block.LastCommit.Round()
vote.BlockID == block.LastBlockID
2017-12-26 15:43:03 -08:00
val := state.LastValidators[i]
vote.Verify(block.ChainID, val.PubKey) == true
2017-12-21 19:18:23 -08:00
2017-12-26 15:43:03 -08:00
talliedVotingPower += val.VotingPower
2017-12-21 19:18:23 -08:00
}
2017-12-26 15:43:03 -08:00
talliedVotingPower > (2/3) * TotalVotingPower(state.LastValidators)
2017-12-21 19:18:23 -08:00
```
Includes one (possibly nil) vote for every current validator.
Non-nil votes must be Precommits.
All votes must be for the same height and round.
All votes must be for the previous block.
All votes must have a valid signature from the corresponding validator.
The sum total of the voting power of the validators that voted
2017-12-26 12:30:27 -08:00
must be greater than 2/3 of the total voting power of the complete validator set.
2017-12-21 19:18:23 -08:00
2017-12-26 15:43:03 -08:00
### Vote
A vote is a signed message broadcast in the consensus for a particular block at a particular height and round.
When stored in the blockchain or propagated over the network, votes are encoded in TMBIN.
For signing, votes are encoded in JSON, and the ChainID is included, in the form of the `CanonicalSignBytes`.
We define a method `Verify` that returns `true` if the signature verifies against the pubkey for the CanonicalSignBytes
using the given ChainID:
2018-01-03 01:46:43 -08:00
```go
2017-12-26 15:43:03 -08:00
func (v Vote) Verify(chainID string, pubKey PubKey) bool {
return pubKey.Verify(v.Signature, CanonicalSignBytes(chainID, v))
}
```
2018-01-24 18:11:07 -08:00
where `pubKey.Verify` performs the appropriate digital signature verification of the `pubKey`
2017-12-26 15:43:03 -08:00
against the given signature and message bytes.
2017-12-21 19:18:23 -08:00
## Evidence
2018-01-21 15:19:38 -08:00
TODO
2017-12-21 19:18:23 -08:00
```
2018-01-21 15:19:38 -08:00
TODO
2017-12-21 19:18:23 -08:00
```
Every piece of evidence contains two conflicting votes from a single validator that
was active at the height indicated in the votes.
The votes must not be too old.
2017-12-26 15:43:03 -08:00
# Execution
Once a block is validated, it can be executed against the state.
2018-01-24 18:11:07 -08:00
The state follows this recursive equation:
2017-12-26 15:43:03 -08:00
2018-01-03 01:46:43 -08:00
```go
2017-12-26 15:43:03 -08:00
state(1) = InitialState
2018-01-21 15:19:38 -08:00
state(h+1) <- Execute(state(h), ABCIApp, block(h))
```
2018-01-24 18:11:07 -08:00
where `InitialState` includes the initial consensus parameters and validator set,
2018-01-21 15:19:38 -08:00
and `ABCIApp` is an ABCI application that can return results and changes to the validator
set (TODO). Execute is defined as:
```go
Execute(s State, app ABCIApp, block Block) State {
TODO: just spell out ApplyBlock here
and remove ABCIResponses struct.
abciResponses := app.ApplyBlock(block)
return State{
LastResults: abciResponses.DeliverTxResults,
AppHash: abciResponses.AppHash,
Validators: UpdateValidators(state.Validators, abciResponses.ValidatorChanges),
LastValidators: state.Validators,
ConsensusParams: UpdateConsensusParams(state.ConsensusParams, abci.Responses.ConsensusParamChanges),
}
}
type ABCIResponses struct {
DeliverTxResults []Result
ValidatorChanges []Validator
ConsensusParamChanges ConsensusParams
AppHash []byte
}
2017-12-26 15:43:03 -08:00
```
2018-01-21 15:19:38 -08:00