mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-28 12:11:44 +00:00
spec.md -> blockchain.md. some fixes
This commit is contained in:
@ -5,11 +5,12 @@ Here we describe the data structures in the Tendermint blockchain and the rules
|
|||||||
# Data Structures
|
# Data Structures
|
||||||
|
|
||||||
The Tendermint blockchains consists of a short list of basic data types:
|
The Tendermint blockchains consists of a short list of basic data types:
|
||||||
blocks, headers, votes, block ids, and signatures.
|
`Block`, `Header`, `Vote`, `BlockID`, and `Signature`.
|
||||||
|
|
||||||
## Block
|
## Block
|
||||||
|
|
||||||
A block consists of a header, a list of transactions, and a list of votes (the commit).
|
A block consists of a header, a list of transactions, a list of votes (the commit),
|
||||||
|
and a list of evidence if malfeasance (ie. signing conflicting votes).
|
||||||
|
|
||||||
```
|
```
|
||||||
type Block struct {
|
type Block struct {
|
||||||
@ -54,14 +55,16 @@ type Header struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Further details on each of this fields is taken up below.
|
||||||
|
|
||||||
## BlockID
|
## BlockID
|
||||||
|
|
||||||
The `BlockID` contains two distinct Merkle roots of the block.
|
The `BlockID` contains two distinct Merkle roots of the block.
|
||||||
The first, used as the block's main hash, is the Merkle root
|
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
|
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
|
the block during consensus, is the Merkle root of the complete serialized block
|
||||||
cut into pieces. The `BlockID` includes these two hashes, as well as the number of
|
cut into parts. The `BlockID` includes these two hashes, as well as the number of
|
||||||
pieces.
|
parts.
|
||||||
|
|
||||||
```
|
```
|
||||||
type BlockID struct {
|
type BlockID struct {
|
||||||
@ -75,7 +78,6 @@ type BlockID struct {
|
|||||||
|
|
||||||
A vote is a signed message from a validator for a particular block.
|
A vote is a signed message from a validator for a particular block.
|
||||||
The vote includes information about the validator signing it.
|
The vote includes information about the validator signing it.
|
||||||
There are two types of votes, but they have identical structure:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
type Vote struct {
|
type Vote struct {
|
||||||
@ -90,11 +92,20 @@ type Vote struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
There are two types of votes:
|
||||||
|
a prevote has `vote.Type == 1` and
|
||||||
|
a precommit has `vote.Type == 2`.
|
||||||
|
|
||||||
## Signature
|
## Signature
|
||||||
|
|
||||||
Tendermint allows for multiple signature schemes to be used by prepending a single type-byte
|
Tendermint allows for multiple signature schemes to be used by prepending a single type-byte
|
||||||
to the signature bytes. Different signatures may also come in different lengths, but this length
|
to the signature bytes. Different signatures may also come with fixed or variable lengths.
|
||||||
is not made explicit. Currently, Tendermint supports Ed25519 and Secp256k1
|
Currently, Tendermint supports Ed25519 and Secp256k1.
|
||||||
|
|
||||||
|
### ED25519
|
||||||
|
|
||||||
|
An ED25519 signature has `Type == 0x1`. It looks like:
|
||||||
|
|
||||||
```
|
```
|
||||||
// Implements Signature
|
// Implements Signature
|
||||||
@ -102,7 +113,15 @@ type Ed25519Signature struct {
|
|||||||
Type int8 = 0x1
|
Type int8 = 0x1
|
||||||
Signature [64]byte
|
Signature [64]byte
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
where `Signature` is the 64 byte signature.
|
||||||
|
|
||||||
|
### Secp256k1
|
||||||
|
|
||||||
|
A `Secp256k1` signature has `Type == 0x2`. It looks like:
|
||||||
|
|
||||||
|
```
|
||||||
// Implements Signature
|
// Implements Signature
|
||||||
type Secp256k1Signature struct {
|
type Secp256k1Signature struct {
|
||||||
Type int8 = 0x2
|
Type int8 = 0x2
|
||||||
@ -110,19 +129,28 @@ type Secp256k1Signature struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
where `Signature` is the DER encoded signature, ie:
|
||||||
|
|
||||||
|
```
|
||||||
|
0x30 <length of whole message> <0x02> <length of R> <R> 0x2 <length of S> <S>.
|
||||||
|
```
|
||||||
|
|
||||||
# Validation
|
# Validation
|
||||||
|
|
||||||
Here we go through every element of a block and describe the rules for validation.
|
Here we describe the validation rules for every element in block.
|
||||||
Blocks which do not satisfy these rules are considered invalid.
|
Blocks which do not satisfy these rules are considered invalid.
|
||||||
|
|
||||||
In the following, `block` refers to the block under consideration,
|
|
||||||
`prevBlock` refers to the `block` at the previous height,
|
|
||||||
`state` refers to an object that keeps track of the validator set
|
|
||||||
and the consensus parameters as they are updated by the application,
|
|
||||||
and `app` refers to the responses returned by the application during the
|
|
||||||
execution of the `prevBlock`.
|
|
||||||
|
|
||||||
We abuse notation by using something that looks like Go, supplemented with English.
|
We abuse notation by using something that looks like Go, supplemented with English.
|
||||||
|
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,
|
||||||
|
`state` keeps track of the validator set
|
||||||
|
and the consensus parameters as they are updated by the application,
|
||||||
|
and `app` is the set of responses returned by the application during the
|
||||||
|
execution of the `prevBlock`. Elements of an object are accessed as expected,
|
||||||
|
ie. `block.Header`. See the definitions of `state` and `app` elsewhere.
|
||||||
|
|
||||||
## Header
|
## Header
|
||||||
|
|
||||||
@ -251,13 +279,14 @@ Arbitrary length array of arbitrary length byte-arrays.
|
|||||||
|
|
||||||
## LastCommit
|
## LastCommit
|
||||||
|
|
||||||
|
The first height is an exception - it requires the LastCommit to be empty:
|
||||||
|
|
||||||
```
|
```
|
||||||
if block.Header.Height == 1 {
|
if block.Header.Height == 1 {
|
||||||
len(b.LastCommit) == 0
|
len(b.LastCommit) == 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The first height is an exception - it requires the LastCommit to be empty.
|
|
||||||
Otherwise, we require:
|
Otherwise, we require:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -278,7 +307,7 @@ for i, vote := range block.LastCommit{
|
|||||||
talliedVotingPower += votingPower
|
talliedVotingPower += votingPower
|
||||||
}
|
}
|
||||||
|
|
||||||
talliedVotingPower > state.LastValidators.TotalVotingPower()
|
talliedVotingPower > (2/3) * state.LastValidators.TotalVotingPower()
|
||||||
```
|
```
|
||||||
|
|
||||||
Includes one (possibly nil) vote for every current validator.
|
Includes one (possibly nil) vote for every current validator.
|
||||||
@ -287,7 +316,7 @@ All votes must be for the same height and round.
|
|||||||
All votes must be for the previous block.
|
All votes must be for the previous block.
|
||||||
All votes must have a valid signature from the corresponding validator.
|
All votes must have a valid signature from the corresponding validator.
|
||||||
The sum total of the voting power of the validators that voted
|
The sum total of the voting power of the validators that voted
|
||||||
must be greater than the total voting power of the complete validator set.
|
must be greater than 2/3 of the total voting power of the complete validator set.
|
||||||
|
|
||||||
## Evidence
|
## Evidence
|
||||||
|
|
Reference in New Issue
Block a user