Browse Source

core: update a few sections (#284)

pull/7804/head
Callum Waters 4 years ago
committed by GitHub
parent
commit
84ee4249ae
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 115 deletions
  1. +13
    -7
      spec/core/data_structures.md
  2. +1
    -0
      spec/core/readme.md
  3. +43
    -108
      spec/core/state.md

+ 13
- 7
spec/core/data_structures.md View File

@ -26,11 +26,13 @@ The Tendermint blockchains consists of a short list of data types:
- [`Validator`](#validator) - [`Validator`](#validator)
- [`ValidatorSet`](#validatorset) - [`ValidatorSet`](#validatorset)
- [`Address`](#address) - [`Address`](#address)
- [`ConsensusParams](#consensusparams)
- [`ConsensusParams`](#consensusparams)
- [`BlockParams`](#blockparams)
- [`EvidenceParams`](#evidenceparams) - [`EvidenceParams`](#evidenceparams)
- [`ValidatorParams`](#validatorparams) - [`ValidatorParams`](#validatorparams)
- [`VersionParams`](#versionparams) - [`VersionParams`](#versionparams)
## Block ## Block
A block consists of a header, transactions, votes (the commit), A block consists of a header, transactions, votes (the commit),
@ -110,7 +112,7 @@ the data in the current block, the previous block, and the results returned by t
| Name | Type | Description | Validation | | Name | Type | Description | Validation |
|-------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Version | [Version](#version) | Version defines the application and protocol verion being used. | Must adhere to the validation rules of [Version](#version) |
| Version | [Version](#version) | Version defines the application and protocol version being used. | Must adhere to the validation rules of [Version](#version) |
| ChainID | String | ChainID is the ID of the chain. This must be unique to your chain. | ChainID must be less than 50 bytes. | | ChainID | String | ChainID is the ID of the chain. This must be unique to your chain. | ChainID must be less than 50 bytes. |
| Height | uint64 | Height is the height for this header. | Must be > 0, >= initialHeight, and == previous Height+1 | | Height | uint64 | Height is the height for this header. | Must be > 0, >= initialHeight, and == previous Height+1 |
| Time | [Time](#time) | The timestamp is equal to the weighted median of validators present in the last commit. Read more on time in the [BFT-time section](../consensus/bft-time.md). Note: the timestamp of a vote must be greater by at least one millisecond than that of the block being voted on. | Time must be >= previous header timestamp + consensus parameters TimeIotaMs. The timestamp of the first block must be equal to the genesis time (since there's no votes to compute the median). | | Time | [Time](#time) | The timestamp is equal to the weighted median of validators present in the last commit. Read more on time in the [BFT-time section](../consensus/bft-time.md). Note: the timestamp of a vote must be greater by at least one millisecond than that of the block being voted on. | Time must be >= previous header timestamp + consensus parameters TimeIotaMs. The timestamp of the first block must be equal to the genesis time (since there's no votes to compute the median). |
@ -127,6 +129,10 @@ the data in the current block, the previous block, and the results returned by t
## Version ## Version
NOTE: that this is more specifically the consensus version and doesn't include information like the
P2P Version. (TODO: we should write a comprehensive document about
versioning that this can refer to)
| Name | type | Description | Validation | | Name | type | Description | Validation |
|-------|--------|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------| |-------|--------|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| Block | uint64 | This number represents the version of the block protocol and must be the same throughout an operational network | Must be equal to protocol version being used in a network (`block.Version.Block == state.Version.Consensus.Block`) | | Block | uint64 | This number represents the version of the block protocol and must be the same throughout an operational network | Must be equal to protocol version being used in a network (`block.Version.Block == state.Version.Consensus.Block`) |
@ -265,7 +271,7 @@ func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
} }
``` ```
### Proposal
## Proposal
Proposal contains height and round for which this proposal is made, BlockID as a unique identifier Proposal contains height and round for which this proposal is made, BlockID as a unique identifier
of proposed block, timestamp, and POLRound (a so-called Proof-of-Lock (POL) round) that is needed for of proposed block, timestamp, and POLRound (a so-called Proof-of-Lock (POL) round) that is needed for
@ -430,7 +436,7 @@ func SumTruncated(bz []byte) []byte {
} }
``` ```
### ConsensusParams
## ConsensusParams
| Name | Type | Description | Field Number | | Name | Type | Description | Field Number |
|-----------|-------------------------------------|------------------------------------------------------------------------------|--------------| |-----------|-------------------------------------|------------------------------------------------------------------------------|--------------|
@ -446,7 +452,7 @@ func SumTruncated(bz []byte) []byte {
| max_bytes | int64 | Max size of a block, in bytes. | 1 | | max_bytes | int64 | Max size of a block, in bytes. | 1 |
| max_gas | int64 | Max sum of `GasWanted` in a proposed block. NOTE: blocks that violate this may be committed if there are Byzantine proposers. It's the application's responsibility to handle this when processing a block! | 2 | | max_gas | int64 | Max sum of `GasWanted` in a proposed block. NOTE: blocks that violate this may be committed if there are Byzantine proposers. It's the application's responsibility to handle this when processing a block! | 2 |
### EvidenceParams
## EvidenceParams
| Name | Type | Description | Field Number | | Name | Type | Description | Field Number |
|--------------------|------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------| |--------------------|------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|
@ -454,13 +460,13 @@ func SumTruncated(bz []byte) []byte {
| max_age_duration | [google.protobuf.Duration](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Duration) | Max age of evidence, in time. It should correspond with an app's "unbonding period" or other similar mechanism for handling [Nothing-At-Stake attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). | 2 | | max_age_duration | [google.protobuf.Duration](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Duration) | Max age of evidence, in time. It should correspond with an app's "unbonding period" or other similar mechanism for handling [Nothing-At-Stake attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). | 2 |
| max_bytes | int64 | maximum size in bytes of total evidence allowed to be entered into a block | 3 | | max_bytes | int64 | maximum size in bytes of total evidence allowed to be entered into a block | 3 |
### ValidatorParams
## ValidatorParams
| Name | Type | Description | Field Number | | Name | Type | Description | Field Number |
|---------------|-----------------|-----------------------------------------------------------------------|--------------| |---------------|-----------------|-----------------------------------------------------------------------|--------------|
| pub_key_types | repeated string | List of accepted public key types. Uses same naming as `PubKey.Type`. | 1 | | pub_key_types | repeated string | List of accepted public key types. Uses same naming as `PubKey.Type`. | 1 |
### VersionParams
## VersionParams
| Name | Type | Description | Field Number | | Name | Type | Description | Field Number |
|-------------|--------|-------------------------------|--------------| |-------------|--------|-------------------------------|--------------|


+ 1
- 0
spec/core/readme.md View File

@ -9,4 +9,5 @@ This section describes the core types and functionality of the Tendermint protoc
- [Core Data Structures](./data_structures.md) - [Core Data Structures](./data_structures.md)
- [Encoding](./encoding.md) - [Encoding](./encoding.md)
- [Genesis](./genesis.md)
- [State](./state.md) - [State](./state.md)

+ 43
- 108
spec/core/state.md View File

@ -1,6 +1,5 @@
# State # State
## State
The state contains information whose cryptographic digest is included in block headers, and thus is The state contains information whose cryptographic digest is included in block headers, and thus is
necessary for validating new blocks. For instance, the validators set and the results of necessary for validating new blocks. For instance, the validators set and the results of
@ -18,13 +17,17 @@ type State struct {
ChainID string ChainID string
InitialHeight int64 InitialHeight int64
LastBlockHeight int64
LastBlockID types.BlockID
LastBlockTime time.Time
Version Version Version Version
LastResults []Result LastResults []Result
AppHash []byte AppHash []byte
LastValidators []Validator
Validators []Validator
NextValidators []Validator
LastValidators ValidatorSet
Validators ValidatorSet
NextValidators ValidatorSet
ConsensusParams ConsensusParams ConsensusParams ConsensusParams
} }
@ -36,129 +39,61 @@ initial height will be `1` in the typical case, `0` is an invalid value.
Note there is a hard-coded limit of 10000 validators. This is inherited from the Note there is a hard-coded limit of 10000 validators. This is inherited from the
limit on the number of votes in a commit. limit on the number of votes in a commit.
### Version
Further information on [`Validator`'s](./data_structures.md#validator),
[`ValidatorSet`'s](./data_structures.md#validatorset) and
[`ConsensusParams`'s](./data_structures.md#consensusparams) can
be found in [data structures](./data_structures.md)
```go
type Version struct {
consensus Consensus
software string
}
```
## Execution
The `Consensus` contains the protocol version for the blockchain and the
application as two `uint64` values:
State gets updated at the end of executing a block. Of specific interest is `ResponseEndBlock` and
`ResponseCommit`
```go ```go
type Consensus struct {
Block uint64
App uint64
}
```
### ResponseDeliverTx
```protobuf
message ResponseDeliverTx {
uint32 code = 1;
bytes data = 2;
string log = 3; // nondeterministic
string info = 4; // nondeterministic
int64 gas_wanted = 5;
int64 gas_used = 6;
repeated Event events = 7
[(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"];
string codespace = 8;
type ResponseEndBlock struct {
ValidatorUpdates []ValidatorUpdate `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"`
ConsensusParamUpdates *types1.ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"`
Events []Event `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"`
} }
``` ```
`ResponseDeliverTx` is the result of executing a transaction against the application.
It returns a result code (`uint32`), an arbitrary byte array (`[]byte`) (ie. a return value), Log (`string`), Info (`string`), GasWanted (`int64`), GasUsed (`int64`), Events (`[]Events`) and a Codespace (`string`).
### Validator
A validator is an active participant in the consensus with a public key and a voting power.
Validator's also contain an address field, which is a hash digest of the PubKey.
where
```go ```go
type Validator struct {
Address []byte
PubKey PubKey
VotingPower int64
type ValidatorUpdate struct {
PubKey crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key"`
Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"`
} }
``` ```
When hashing the Validator struct, the address is not included,
because it is redundant with the pubkey.
The `state.Validators`, `state.LastValidators`, and `state.NextValidators`,
must always be sorted by voting power, so that there is a canonical order for
computing the MerkleRoot.
We also define a `TotalVotingPower` function, to return the total voting power:
and
```go ```go
func TotalVotingPower(vals []Validators) int64{
sum := 0
for v := range vals{
sum += v.VotingPower
}
return sum
type ResponseCommit struct {
// reserve 1
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
RetainHeight int64 `protobuf:"varint,3,opt,name=retain_height,json=retainHeight,proto3" json:"retain_height,omitempty"`
} }
``` ```
### ConsensusParams
`ValidatorUpdates` are used to add and remove validators to the current set as well as update
validator power. Setting validator power to 0 in `ValidatorUpdate` will cause the validator to be
removed. `ConsensusParams` are safely copied across (i.e. if a field is nil it gets ignored) and the
`Data` from the `ResponseCommit` is used as the `AppHash`
ConsensusParams define various limits for blockchain data structures.
Like validator sets, they are set during genesis and can be updated by the application through ABCI.
When hashed, only a subset of the params are included, to allow the params to
evolve without breaking the header.
```protobuf
message ConsensusParams {
BlockParams block = 1;
EvidenceParams evidence = 2;
ValidatorParams validator = 3;
VersionParams version = 4;
}
```
## Version
```go ```go
type hashedParams struct {
BlockMaxBytes int64
BlockMaxGas int64
}
func HashConsensusParams() []byte {
SHA256(hashedParams{
BlockMaxBytes: params.Block.MaxBytes,
BlockMaxGas: params.Block.MaxGas,
})
type Version struct {
consensus Consensus
software string
} }
``` ```
```protobuf
message BlockParams {
int64 max_bytes = 1;
int64 max_gas = 2;
int64 time_iota_ms = 3; // not exposed to the application
}
message EvidenceParams {
int64 max_age_num_blocks = 1;
google.protobuf.Duration max_age_duration = 2;
uint32 max_num = 3;
}
message ValidatorParams {
repeated string pub_key_types = 1;
}
message VersionParams {
uint64 AppVersion = 1;
}
```
[`Consensus`](./data_structures.md#version) contains the protocol version for the blockchain and the
application.
#### Block
## Block
The total size of a block is limited in bytes by the `ConsensusParams.Block.MaxBytes`. The total size of a block is limited in bytes by the `ConsensusParams.Block.MaxBytes`.
Proposed blocks must be less than this size, and will be considered invalid Proposed blocks must be less than this size, and will be considered invalid
@ -167,10 +102,7 @@ otherwise.
Blocks should additionally be limited by the amount of "gas" consumed by the Blocks should additionally be limited by the amount of "gas" consumed by the
transactions in the block, though this is not yet implemented. transactions in the block, though this is not yet implemented.
The minimal time between consecutive blocks is controlled by the
`ConsensusParams.Block.TimeIotaMs`.
#### Evidence
## Evidence
For evidence in a block to be valid, it must satisfy: For evidence in a block to be valid, it must satisfy:
@ -179,7 +111,10 @@ block.Header.Time-evidence.Time < ConsensusParams.Evidence.MaxAgeDuration &&
block.Header.Height-evidence.Height < ConsensusParams.Evidence.MaxAgeNumBlocks block.Header.Height-evidence.Height < ConsensusParams.Evidence.MaxAgeNumBlocks
``` ```
#### Validator
A block must not contain more than `ConsensusParams.Evidence.MaxBytes` of evidence. This is
implemented to mitigate spam attacks.
## Validator
Validators from genesis file and `ResponseEndBlock` must have pubkeys of type ∈ Validators from genesis file and `ResponseEndBlock` must have pubkeys of type ∈
`ConsensusParams.Validator.PubKeyTypes`. `ConsensusParams.Validator.PubKeyTypes`.

Loading…
Cancel
Save