Skip to content

Commit

Permalink
[types] hash of ConsensusParams includes only a subset of fields (ten…
Browse files Browse the repository at this point in the history
…dermint#3165)

* types: dont hash entire ConsensusParams

* update encoding spec

* update blockchain spec

* spec: consensus params hash

* changelog
  • Loading branch information
ebuchman authored Jan 19, 2019
1 parent 40c887b commit 4f87691
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 84 deletions.
10 changes: 7 additions & 3 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Special thanks to external contributors on this release:
### BREAKING CHANGES:

* CLI/RPC/Config
- [types] consistent field order of `CanonicalVote` and `CanonicalProposal`

* Apps

Expand All @@ -16,6 +15,11 @@ Special thanks to external contributors on this release:

* Blockchain Protocol
* [merkle] \#2713 Merkle trees now match the RFC 6962 specification
* [types] \#3078 Re-order Timestamp and BlockID in CanonicalVote so it's
consistent with CanonicalProposal (BlockID comes
first)
* [types] \#3165 Hash of ConsensusParams only includes BlockSize.MaxBytes and
BlockSize.MaxGas

* P2P Protocol
- [consensus] \#2960 normalize priorities to not exceed `2*TotalVotingPower` to mitigate unfair proposer selection
Expand All @@ -24,8 +28,8 @@ Special thanks to external contributors on this release:
### FEATURES:

### IMPROVEMENTS:
- [rpc] \#3065 return maxPerPage (100), not defaultPerPage (30) if `per_page` is greater than the max 100.
- [instrumentation] \#3082 add 'chain_id' label for all metrics
- [rpc] \#3065 Return maxPerPage (100), not defaultPerPage (30) if `per_page` is greater than the max 100.
- [instrumentation] \#3082 Add `chain_id` label for all metrics

### BUG FIXES:
- [log] \#3060 Fix year format
Expand Down
75 changes: 38 additions & 37 deletions docs/spec/blockchain/blockchain.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type Header struct {

// hashes of block data
LastCommitHash []byte // commit from validators from the last block
DataHash []byte // Merkle root of transactions
DataHash []byte // MerkleRoot of transactions

// hashes from the app output from the prev block
ValidatorsHash []byte // validators for the current block
Expand Down Expand Up @@ -83,25 +83,27 @@ type Version struct {
## 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
cut into parts. The `BlockID` includes these two hashes, as well as the number of
parts.
The first, used as the block's main hash, is the MerkleRoot
of all the fields in the header (ie. `MerkleRoot(header)`.
The second, used for secure gossipping of the block during consensus,
is the MerkleRoot of the complete serialized block
cut into parts (ie. `MerkleRoot(MakeParts(block))`).
The `BlockID` includes these two hashes, as well as the number of
parts (ie. `len(MakeParts(block))`)
```go
type BlockID struct {
Hash []byte
Parts PartsHeader
PartsHeader PartSetHeader
}

type PartsHeader struct {
Hash []byte
type PartSetHeader struct {
Total int32
Hash []byte
}
```
TODO: link to details of merkle sums.
See [MerkleRoot](/docs/spec/blockchain/encoding.md#MerkleRoot) for details.
## Time
Expand Down Expand Up @@ -142,12 +144,12 @@ The vote includes information about the validator signing it.
```go
type Vote struct {
Type SignedMsgType // byte
Type byte
Height int64
Round int
Timestamp time.Time
BlockID BlockID
ValidatorAddress Address
Timestamp Time
ValidatorAddress []byte
ValidatorIndex int
Signature []byte
}
Expand All @@ -160,8 +162,8 @@ a _precommit_ has `vote.Type == 2`.
## Signature
Signatures in Tendermint are raw bytes representing the underlying signature.
The only signature scheme currently supported for Tendermint validators is
ED25519. The signature is the raw 64-byte ED25519 signature.
See the [signature spec](/docs/spec/blockchain/encoding.md#key-types) for more.
## EvidenceData
Expand All @@ -188,6 +190,8 @@ type DuplicateVoteEvidence struct {
}
```
See the [pubkey spec](/docs/spec/blockchain/encoding.md#key-types) for more.
## Validation
Here we describe the validation rules for every element in a block.
Expand All @@ -205,7 +209,7 @@ the current version of the `state` corresponds to the state
after executing transactions from the `prevBlock`.
Elements of an object are accessed as expected,
ie. `block.Header`.
See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`.
See the [definition of `State`](/docs/spec/blockchain/state.md).
### Header
Expand Down Expand Up @@ -284,66 +288,63 @@ The first block has `block.Header.TotalTxs = block.Header.NumberTxs`.
LastBlockID is the previous block's BlockID:
```go
prevBlockParts := MakeParts(prevBlock, state.LastConsensusParams.BlockGossip.BlockPartSize)
prevBlockParts := MakeParts(prevBlock)
block.Header.LastBlockID == BlockID {
Hash: SimpleMerkleRoot(prevBlock.Header),
Hash: MerkleRoot(prevBlock.Header),
PartsHeader{
Hash: SimpleMerkleRoot(prevBlockParts),
Hash: MerkleRoot(prevBlockParts),
Total: len(prevBlockParts),
},
}
```
Note: it depends on the ConsensusParams,
which are held in the `state` and may be updated by the application.
The first block has `block.Header.LastBlockID == BlockID{}`.
### LastCommitHash
```go
block.Header.LastCommitHash == SimpleMerkleRoot(block.LastCommit)
block.Header.LastCommitHash == MerkleRoot(block.LastCommit)
```
Simple Merkle root of the votes included in the block.
MerkleRoot of the votes included in the block.
These are the votes that committed the previous block.
The first block has `block.Header.LastCommitHash == []byte{}`
### DataHash
```go
block.Header.DataHash == SimpleMerkleRoot(block.Txs.Txs)
block.Header.DataHash == MerkleRoot(block.Txs.Txs)
```
Simple Merkle root of the transactions included in the block.
MerkleRoot of the transactions included in the block.
### ValidatorsHash
```go
block.ValidatorsHash == SimpleMerkleRoot(state.Validators)
block.ValidatorsHash == MerkleRoot(state.Validators)
```
Simple Merkle root of the current validator set that is committing the block.
MerkleRoot of the current validator set that is committing the block.
This can be used to validate the `LastCommit` included in the next block.
### NextValidatorsHash
```go
block.NextValidatorsHash == SimpleMerkleRoot(state.NextValidators)
block.NextValidatorsHash == MerkleRoot(state.NextValidators)
```
Simple Merkle root of the next validator set that will be the validator set that commits the next block.
MerkleRoot of the next validator set that will be the validator set that commits the next block.
This is included so that the current validator set gets a chance to sign the
next validator sets Merkle root.
### ConsensusParamsHash
### ConsensusHash
```go
block.ConsensusParamsHash == TMHASH(amino(state.ConsensusParams))
block.ConsensusHash == state.ConsensusParams.Hash()
```
Hash of the amino-encoded consensus parameters.
Hash of the amino-encoding of a subset of the consensus parameters.
### AppHash
Expand All @@ -358,20 +359,20 @@ The first block has `block.Header.AppHash == []byte{}`.
### LastResultsHash
```go
block.ResultsHash == SimpleMerkleRoot(state.LastResults)
block.ResultsHash == MerkleRoot(state.LastResults)
```
Simple Merkle root of the results of the transactions in the previous block.
MerkleRoot of the results of the transactions in the previous block.
The first block has `block.Header.ResultsHash == []byte{}`.
## EvidenceHash
```go
block.EvidenceHash == SimpleMerkleRoot(block.Evidence)
block.EvidenceHash == MerkleRoot(block.Evidence)
```
Simple Merkle root of the evidence of Byzantine behaviour included in this block.
MerkleRoot of the evidence of Byzantine behaviour included in this block.
### ProposerAddress
Expand Down
Loading

0 comments on commit 4f87691

Please sign in to comment.