Skip to content

types/Header: ambiguous comment about Hash() returning nil if "required" fields are missing #723

@odeke-em

Description

@odeke-em

So currently in

tendermint/types/block.go

Lines 172 to 188 in 7682ad9

// NOTE: hash is nil if required fields are missing.
func (h *Header) Hash() data.Bytes {
if len(h.ValidatorsHash) == 0 {
return nil
}
return merkle.SimpleHashFromMap(map[string]interface{}{
"ChainID": h.ChainID,
"Height": h.Height,
"Time": h.Time,
"NumTxs": h.NumTxs,
"LastBlockID": h.LastBlockID,
"LastCommit": h.LastCommitHash,
"Data": h.DataHash,
"Validators": h.ValidatorsHash,
"App": h.AppHash,
})
}

The comment says:
// NOTE: hash is nil if required fields are missing.

But that's a bit unclear/over-generalized. Perhaps later on we should improve that doc to say it returns nil if ValidatorsHash is nil because I'd have thought not including other fields would also cause it to fail.

package test_it

import (
        "testing"

        "github.com/google/gofuzz"

        "github.com/tendermint/tendermint/types"
)

func TestFuzzMerkleHash(t *testing.T) {
        f := fuzz.New()

        n := 100000
        nonNilCount := uint64(0)
        for i := 0; i < n; i++ {
                hdr := new(types.Header)
                f.Fuzz(hdr)
                hash := hdr.Hash()
                if hash != nil {
                        nonNilCount += 1
                }
        }
        t.Logf("nonNilCount: %d/%d", nonNilCount, n)
}

Shooting at it with a fuzzer reveals that most times "randomly" folks can get it right 80% with guesses so that comment perhaps needs an update

Emmanuels-MacBook-Pro-2:types emmanuelodeke$ go test -v -run=FuzzMerkle
=== RUN   TestFuzzMerkleHash
--- PASS: TestFuzzMerkleHash (3.47s)
	hdr_test.go:595: nonNilCount: 80128/100000
Emmanuels-MacBook-Pro-2:types emmanuelodeke$ go test -v -run=FuzzMerkle
=== RUN   TestFuzzMerkleHash
--- PASS: TestFuzzMerkleHash (3.55s)
	hdr_test.go:595: nonNilCount: 80131/100000
Emmanuels-MacBook-Pro-2:types emmanuelodeke$ go test -v -run=FuzzMerkle
=== RUN   TestFuzzMerkleHash
--- PASS: TestFuzzMerkleHash (3.63s)
	hdr_test.go:595: nonNilCount: 80074/100000
Emmanuels-MacBook-Pro-2:types emmanuelodeke$ go test -v -run=FuzzMerkle
=== RUN   TestFuzzMerkleHash
--- PASS: TestFuzzMerkleHash (4.08s)
	hdr_test.go:595: nonNilCount: 80426/100000
Emmanuels-MacBook-Pro-2:types emmanuelodeke$ go test -v -run=FuzzMerkle
=== RUN   TestFuzzMerkleHash
--- PASS: TestFuzzMerkleHash (3.59s)
	hdr_test.go:595: nonNilCount: 80017/100000

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions