mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-06 21:36:26 +00:00
update spec for Merkle RFC 6962 (#3175)
* spec: specify when MerkleRoot is on hashes * remove unnecessary hash methods * update changelog * fix test
This commit is contained in:
@@ -51,7 +51,7 @@ type Header struct {
|
||||
|
||||
// hashes of block data
|
||||
LastCommitHash []byte // commit from validators from the last block
|
||||
DataHash []byte // MerkleRoot of transactions
|
||||
DataHash []byte // MerkleRoot of transaction hashes
|
||||
|
||||
// hashes from the app output from the prev block
|
||||
ValidatorsHash []byte // validators for the current block
|
||||
@@ -303,7 +303,7 @@ The first block has `block.Header.LastBlockID == BlockID{}`.
|
||||
### LastCommitHash
|
||||
|
||||
```go
|
||||
block.Header.LastCommitHash == MerkleRoot(block.LastCommit)
|
||||
block.Header.LastCommitHash == MerkleRoot(block.LastCommit.Precommits)
|
||||
```
|
||||
|
||||
MerkleRoot of the votes included in the block.
|
||||
@@ -314,10 +314,15 @@ The first block has `block.Header.LastCommitHash == []byte{}`
|
||||
### DataHash
|
||||
|
||||
```go
|
||||
block.Header.DataHash == MerkleRoot(block.Txs.Txs)
|
||||
block.Header.DataHash == MerkleRoot(Hashes(block.Txs.Txs))
|
||||
```
|
||||
|
||||
MerkleRoot of the transactions included in the block.
|
||||
MerkleRoot of the hashes of transactions included in the block.
|
||||
|
||||
Note the transactions are hashed before being included in the Merkle tree,
|
||||
so the leaves of the Merkle tree are the hashes, not the transactions
|
||||
themselves. This is because transaction hashes are regularly used as identifiers for
|
||||
transactions.
|
||||
|
||||
### ValidatorsHash
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ func innerHash(left []byte, right []byte) []byte {
|
||||
// largest power of 2 less than k
|
||||
func getSplitPoint(k int) { ... }
|
||||
|
||||
func MerkleRoot(leafs [][]byte) []byte{
|
||||
func MerkleRoot(items [][]byte) []byte{
|
||||
switch len(items) {
|
||||
case 0:
|
||||
return nil
|
||||
@@ -228,10 +228,20 @@ func MerkleRoot(leafs [][]byte) []byte{
|
||||
}
|
||||
```
|
||||
|
||||
Note: `MerkleRoot` operates on items which are arbitrary byte arrays, not
|
||||
necessarily hashes. For items which need to be hashed first, we introduce the
|
||||
`Hashes` function:
|
||||
|
||||
```
|
||||
func Hashes(items [][]byte) [][]byte {
|
||||
return SHA256 of each item
|
||||
}
|
||||
```
|
||||
|
||||
Note: we will abuse notion and invoke `MerkleRoot` with arguments of type `struct` or type `[]struct`.
|
||||
For `struct` arguments, we compute a `[][]byte` containing the hash of each
|
||||
For `struct` arguments, we compute a `[][]byte` containing the amino encoding of each
|
||||
field in the struct, in the same order the fields appear in the struct.
|
||||
For `[]struct` arguments, we compute a `[][]byte` by hashing the individual `struct` elements.
|
||||
For `[]struct` arguments, we compute a `[][]byte` by amino encoding the individual `struct` elements.
|
||||
|
||||
### Simple Merkle Proof
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ 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 by sorted by validator address,
|
||||
so that there is a canonical order for computing the SimpleMerkleRoot.
|
||||
so that there is a canonical order for computing the MerkleRoot.
|
||||
|
||||
We also define a `TotalVotingPower` function, to return the total voting power:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user