modify evidence hashes

This commit is contained in:
Callum Waters
2021-04-09 23:25:30 +02:00
parent d0828f3454
commit 6c095dcdb8
6 changed files with 109 additions and 29 deletions
+14 -12
View File
@@ -292,18 +292,20 @@ func (l *LightClientAttackEvidence) ConflictingHeaderIsInvalid(trustedHeader *He
}
// Hash returns the hash of the header and the commonHeight. This is designed to cause hash collisions
// with evidence that have the same conflicting header and common height but different permutations
// of validator commit signatures. The reason for this is that we don't want to allow several
// permutations of the same evidence to be committed on chain. Ideally we commit the header with the
// most commit signatures (captures the most byzantine validators) but anything greater than 1/3 is sufficient.
// Hash returns the SHA256 hash of the header, commit, common height, total
// voting power, byzantine validators and timestamp
func (l *LightClientAttackEvidence) Hash() []byte {
buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutVarint(buf, l.CommonHeight)
bz := make([]byte, tmhash.Size+n)
copy(bz[:tmhash.Size-1], l.ConflictingBlock.Hash().Bytes())
copy(bz[tmhash.Size:], buf)
return tmhash.Sum(bz)
buf := new(bytes.Buffer)
buf.Write(l.ConflictingBlock.Header.Hash())
buf.Write(l.ConflictingBlock.Commit.Hash())
_ = binary.Write(buf, binary.LittleEndian, l.CommonHeight)
_ = binary.Write(buf, binary.LittleEndian, l.TotalVotingPower)
for _, val := range l.ByzantineValidators {
_, _ = buf.Write(val.Bytes())
}
timeBytes, _ := l.Timestamp.MarshalBinary()
buf.Write(timeBytes)
return tmhash.Sum(buf.Bytes())
}
// Height returns the last height at which the primary provider and witness provider had the same header.
@@ -422,7 +424,7 @@ func (evl EvidenceList) Hash() []byte {
// the Evidence size is capped.
evidenceBzs := make([][]byte, len(evl))
for i := 0; i < len(evl); i++ {
evidenceBzs[i] = evl[i].Bytes()
evidenceBzs[i] = evl[i].Hash()
}
return merkle.HashFromByteSlices(evidenceBzs)
}
+10 -1
View File
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"github.com/tendermint/tendermint/crypto/tmhash"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
@@ -149,13 +150,21 @@ func (sh SignedHeader) ValidateBasic(chainID string) error {
if sh.Commit.Height != sh.Height {
return fmt.Errorf("header and commit height mismatch: %d vs %d", sh.Height, sh.Commit.Height)
}
if hhash, chash := sh.Hash(), sh.Commit.BlockID.Hash; !bytes.Equal(hhash, chash) {
if hhash, chash := sh.Header.Hash(), sh.Commit.BlockID.Hash; !bytes.Equal(hhash, chash) {
return fmt.Errorf("commit signs block %X, header is block %X", chash, hhash)
}
return nil
}
// Hash returns the SHA256 hash of both the header and the commit that signed that header
func (sh SignedHeader) Hash() []byte {
bz := make([]byte, tmhash.Size*2)
copy(bz[:tmhash.Size-1], sh.Header.Hash())
copy(bz[tmhash.Size:], sh.Commit.Hash())
return tmhash.Sum(bz)
}
// String returns a string representation of SignedHeader.
func (sh SignedHeader) String() string {
return sh.StringIndented("")