Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

block hash abi encoded #5

Draft
wants to merge 2 commits into
base: version-0.37.5
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 140 additions & 86 deletions proto/tendermint/types/types.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions proto/tendermint/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ message Part {
message BlockID {
bytes hash = 1;
PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false];
bytes hash_abi_encoded = 3;
}

// --------------------------------
Expand Down
60 changes: 55 additions & 5 deletions types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@
}
}

// fillHeader fills in any remaining header fields that are a function of the block data
func (b *Block) fillHeaderAbiEncoded() {
if b.LastCommitHash == nil {

Check failure on line 123 in types/block.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA9003: empty branch (staticcheck)
// b.LastCommitHash = b.LastCommit.Hash()
// TODO(blas)
}
if b.DataHash == nil {

Check failure on line 127 in types/block.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA9003: empty branch (staticcheck)
// b.DataHash = b.Data.Hash()
// TODO(blas)

}
if b.EvidenceHash == nil {

Check failure on line 132 in types/block.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA9003: empty branch (staticcheck)
// b.EvidenceHash = b.Evidence.Hash()
// TODO(blas)
}
}

// Hash computes and returns the block hash.
// If the block is incomplete, block hash is nil for safety.
func (b *Block) Hash() cmtbytes.HexBytes {
Expand All @@ -134,6 +151,22 @@
return b.Header.Hash()
}

// Hash computes and returns the block hash.
// If the block is incomplete, block hash is nil for safety.
func (b *Block) HashAbiEncoded() cmtbytes.HexBytes {
if b == nil {
return nil
}
b.mtx.Lock()
defer b.mtx.Unlock()

if b.LastCommit == nil {
return nil
}
b.fillHeaderAbiEncoded()
return b.Header.HashAbiEncoded()
}

// MakePartSet returns a PartSet containing parts of a serialized block.
// This is the form in which the block is gossipped to peers.
// CONTRACT: partSize is greater than zero.
Expand Down Expand Up @@ -474,6 +507,17 @@
})
}

// Hash returns the hash of the header.
// It computes a Merkle tree from the header fields
// ordered as they appear in the Header.
// Returns nil if ValidatorHash is missing,
// since a Header is not valid unless there is
// a ValidatorsHash (corresponding to the validator set).
func (h *Header) HashAbiEncoded() cmtbytes.HexBytes {
// TODO(blas)
return nil
}

// StringIndented returns an indented string representation of the header.
func (h *Header) StringIndented(indent string) string {
if h == nil {
Expand Down Expand Up @@ -1159,14 +1203,15 @@

// BlockID
type BlockID struct {
Hash cmtbytes.HexBytes `json:"hash"`
PartSetHeader PartSetHeader `json:"parts"`
Hash cmtbytes.HexBytes `json:"hash"`
PartSetHeader PartSetHeader `json:"parts"`
HashAbiEncoded cmtbytes.HexBytes `json:"hash"`

Check failure on line 1208 in types/block.go

View workflow job for this annotation

GitHub Actions / golangci-lint

structtag: struct field HashAbiEncoded repeats json tag "hash" also at block.go:1206 (govet)
}

// Equals returns true if the BlockID matches the given BlockID
func (blockID BlockID) Equals(other BlockID) bool {
return bytes.Equal(blockID.Hash, other.Hash) &&
blockID.PartSetHeader.Equals(other.PartSetHeader)
blockID.PartSetHeader.Equals(other.PartSetHeader) && bytes.Equal(blockID.HashAbiEncoded, other.HashAbiEncoded)
}

// Key returns a machine-readable string representation of the BlockID
Expand All @@ -1186,6 +1231,9 @@
if err := ValidateHash(blockID.Hash); err != nil {
return fmt.Errorf("wrong Hash")
}
if err := ValidateHash(blockID.HashAbiEncoded); err != nil {
return fmt.Errorf("wrong Hash")
}
if err := blockID.PartSetHeader.ValidateBasic(); err != nil {
return fmt.Errorf("wrong PartSetHeader: %v", err)
}
Expand Down Expand Up @@ -1222,8 +1270,9 @@
}

return cmtproto.BlockID{
Hash: blockID.Hash,
PartSetHeader: blockID.PartSetHeader.ToProto(),
Hash: blockID.Hash,
PartSetHeader: blockID.PartSetHeader.ToProto(),
HashAbiEncoded: blockID.HashAbiEncoded,
}
}

Expand All @@ -1242,6 +1291,7 @@

blockID.PartSetHeader = *ph
blockID.Hash = bID.Hash
blockID.HashAbiEncoded = bID.HashAbiEncoded

return blockID, blockID.ValidateBasic()
}
2 changes: 1 addition & 1 deletion types/block_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type BlockMeta struct {
// NewBlockMeta returns a new BlockMeta.
func NewBlockMeta(block *Block, blockParts *PartSet) *BlockMeta {
return &BlockMeta{
BlockID: BlockID{block.Hash(), blockParts.Header()},
BlockID: BlockID{block.Hash(), blockParts.Header(), block.HashAbiEncoded()},
BlockSize: block.Size(),
Header: block.Header,
NumTxs: len(block.Data.Txs),
Expand Down
7 changes: 4 additions & 3 deletions types/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,13 @@ func TestBlockString(t *testing.T) {

func makeBlockIDRandom() BlockID {
var (
blockHash = make([]byte, tmhash.Size)
partSetHash = make([]byte, tmhash.Size)
blockHash = make([]byte, tmhash.Size)
blockHashAbiEncoded = make([]byte, tmhash.Size)
partSetHash = make([]byte, tmhash.Size)
)
rand.Read(blockHash) //nolint: errcheck // ignore errcheck for read
rand.Read(partSetHash) //nolint: errcheck // ignore errcheck for read
return BlockID{blockHash, PartSetHeader{123, partSetHash}}
return BlockID{blockHash, PartSetHeader{123, partSetHash}, blockHashAbiEncoded}
}

func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) BlockID {
Expand Down
4 changes: 2 additions & 2 deletions types/proposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func TestProposalVerifySignature(t *testing.T) {

prop := NewProposal(
4, 2, 2,
BlockID{cmtrand.Bytes(tmhash.Size), PartSetHeader{777, cmtrand.Bytes(tmhash.Size)}})
BlockID{cmtrand.Bytes(tmhash.Size), PartSetHeader{777, cmtrand.Bytes(tmhash.Size)}, cmtrand.Bytes(tmhash.Size)})
p := prop.ToProto()
signBytes := ProposalSignBytes("test_chain_id", p)

Expand Down Expand Up @@ -136,7 +136,7 @@ func TestProposalValidateBasic(t *testing.T) {
{"Invalid Round", func(p *Proposal) { p.Round = -1 }, true},
{"Invalid POLRound", func(p *Proposal) { p.POLRound = -2 }, true},
{"Invalid BlockId", func(p *Proposal) {
p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}}
p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}, []byte{1, 2, 3}}
}, true},
{"Invalid Signature", func(p *Proposal) {
p.Signature = make([]byte, 0)
Expand Down
23 changes: 13 additions & 10 deletions types/vote_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestVoteSet_AddVote_Good(t *testing.T) {
Round: round,
Type: cmtproto.PrevoteType,
Timestamp: cmttime.Now(),
BlockID: BlockID{nil, PartSetHeader{}},
BlockID: BlockID{nil, PartSetHeader{}, nil},
}
_, err = signAddVote(val0, vote, voteSet)
require.NoError(t, err)
Expand All @@ -56,7 +56,7 @@ func TestVoteSet_AddVote_Bad(t *testing.T) {
Round: round,
Timestamp: cmttime.Now(),
Type: cmtproto.PrevoteType,
BlockID: BlockID{nil, PartSetHeader{}},
BlockID: BlockID{nil, PartSetHeader{}, nil},
}

// val0 votes for nil.
Expand Down Expand Up @@ -131,7 +131,7 @@ func TestVoteSet_2_3Majority(t *testing.T) {
Round: round,
Type: cmtproto.PrevoteType,
Timestamp: cmttime.Now(),
BlockID: BlockID{nil, PartSetHeader{}},
BlockID: BlockID{nil, PartSetHeader{}, nil},
}
// 6 out of 10 voted for nil.
for i := int32(0); i < 6; i++ {
Expand Down Expand Up @@ -175,6 +175,7 @@ func TestVoteSet_2_3MajorityRedux(t *testing.T) {
voteSet, _, privValidators := randVoteSet(height, round, cmtproto.PrevoteType, 100, 1)

blockHash := crypto.CRandBytes(32)
blockHashAbiEncoded := crypto.CRandBytes(32)
blockPartsTotal := uint32(123)
blockPartSetHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)}

Expand All @@ -185,7 +186,7 @@ func TestVoteSet_2_3MajorityRedux(t *testing.T) {
Round: round,
Timestamp: cmttime.Now(),
Type: cmtproto.PrevoteType,
BlockID: BlockID{blockHash, blockPartSetHeader},
BlockID: BlockID{blockHash, blockPartSetHeader, blockHashAbiEncoded},
}

// 66 out of 100 voted for nil.
Expand Down Expand Up @@ -264,7 +265,7 @@ func TestVoteSet_2_3MajorityRedux(t *testing.T) {
_, err = signAddVote(privValidators[70], vote, voteSet)
require.NoError(t, err)
blockID, ok = voteSet.TwoThirdsMajority()
assert.True(t, ok && blockID.Equals(BlockID{blockHash, blockPartSetHeader}),
assert.True(t, ok && blockID.Equals(BlockID{blockHash, blockPartSetHeader, blockHashAbiEncoded}),
"there should be 2/3 majority")
}
}
Expand All @@ -274,6 +275,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
voteSet, _, privValidators := randVoteSet(height, round, cmtproto.PrevoteType, 4, 1)
blockHash1 := cmtrand.Bytes(32)
blockHash2 := cmtrand.Bytes(32)
blockHashAbiEncoded := cmtrand.Bytes(32)

voteProto := &Vote{
ValidatorAddress: nil,
Expand All @@ -282,7 +284,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
Round: round,
Timestamp: cmttime.Now(),
Type: cmtproto.PrevoteType,
BlockID: BlockID{nil, PartSetHeader{}},
BlockID: BlockID{nil, PartSetHeader{}, nil},
}

val0, err := privValidators[0].GetPubKey()
Expand All @@ -307,7 +309,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
}

// start tracking blockHash1
err = voteSet.SetPeerMaj23("peerA", BlockID{blockHash1, PartSetHeader{}})
err = voteSet.SetPeerMaj23("peerA", BlockID{blockHash1, PartSetHeader{}, blockHashAbiEncoded})
require.NoError(t, err)

// val0 votes again for blockHash1.
Expand All @@ -319,7 +321,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
}

// attempt tracking blockHash2, should fail because already set for peerA.
err = voteSet.SetPeerMaj23("peerA", BlockID{blockHash2, PartSetHeader{}})
err = voteSet.SetPeerMaj23("peerA", BlockID{blockHash2, PartSetHeader{}, blockHashAbiEncoded})
require.Error(t, err)

// val0 votes again for blockHash1.
Expand Down Expand Up @@ -371,7 +373,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
}

// now attempt tracking blockHash1
err = voteSet.SetPeerMaj23("peerB", BlockID{blockHash1, PartSetHeader{}})
err = voteSet.SetPeerMaj23("peerB", BlockID{blockHash1, PartSetHeader{}, blockHashAbiEncoded})
require.NoError(t, err)

// val2 votes for blockHash1.
Expand Down Expand Up @@ -402,6 +404,7 @@ func TestVoteSet_MakeCommit(t *testing.T) {
height, round := int64(1), int32(0)
voteSet, _, privValidators := randVoteSet(height, round, cmtproto.PrecommitType, 10, 1)
blockHash, blockPartSetHeader := crypto.CRandBytes(32), PartSetHeader{123, crypto.CRandBytes(32)}
blockHashAbiEncoded := crypto.CRandBytes(32)

voteProto := &Vote{
ValidatorAddress: nil,
Expand All @@ -410,7 +413,7 @@ func TestVoteSet_MakeCommit(t *testing.T) {
Round: round,
Timestamp: cmttime.Now(),
Type: cmtproto.PrecommitType,
BlockID: BlockID{blockHash, blockPartSetHeader},
BlockID: BlockID{blockHash, blockPartSetHeader, blockHashAbiEncoded},
}

// 6 out of 10 voted for some block.
Expand Down
2 changes: 1 addition & 1 deletion types/vote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func TestVoteValidateBasic(t *testing.T) {
{"Zero Height", func(v *Vote) { v.Height = 0 }, true},
{"Negative Round", func(v *Vote) { v.Round = -1 }, true},
{"Invalid BlockID", func(v *Vote) {
v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}}
v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}, []byte{1, 2, 3}}
}, true},
{"Invalid Address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }, true},
{"Invalid ValidatorIndex", func(v *Vote) { v.ValidatorIndex = -1 }, true},
Expand Down
Loading