mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-30 13:11:38 +00:00
Make txs and evidencelist use merkle.SimpleHashFromBytes to create hash (#2635)
This is a performance regression, but will also spare the types directory from knowing about RFC 6962, which is a more correct abstraction. For txs this performance hit will be fixed soon with #2603. For evidence, the performance impact is negligible due to it being capped at a small number.
This commit is contained in:
@ -576,7 +576,6 @@ func (sh SignedHeader) StringIndented(indent string) string {
|
||||
indent, sh.Header.StringIndented(indent+" "),
|
||||
indent, sh.Commit.StringIndented(indent+" "),
|
||||
indent)
|
||||
return ""
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -660,7 +659,6 @@ func (data *EvidenceData) StringIndented(indent string) string {
|
||||
%s}#%v`,
|
||||
indent, strings.Join(evStrings, "\n"+indent+" "),
|
||||
indent, data.hash)
|
||||
return ""
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
@ -55,6 +55,7 @@ func (err *ErrEvidenceOverflow) Error() string {
|
||||
type Evidence interface {
|
||||
Height() int64 // height of the equivocation
|
||||
Address() []byte // address of the equivocating validator
|
||||
Bytes() []byte // bytes which compromise the evidence
|
||||
Hash() []byte // hash of the evidence
|
||||
Verify(chainID string, pubKey crypto.PubKey) error // verify the evidence
|
||||
Equal(Evidence) bool // check equality of evidence
|
||||
@ -88,6 +89,8 @@ type DuplicateVoteEvidence struct {
|
||||
VoteB *Vote
|
||||
}
|
||||
|
||||
var _ Evidence = &DuplicateVoteEvidence{}
|
||||
|
||||
// String returns a string representation of the evidence.
|
||||
func (dve *DuplicateVoteEvidence) String() string {
|
||||
return fmt.Sprintf("VoteA: %v; VoteB: %v", dve.VoteA, dve.VoteB)
|
||||
@ -104,6 +107,11 @@ func (dve *DuplicateVoteEvidence) Address() []byte {
|
||||
return dve.PubKey.Address()
|
||||
}
|
||||
|
||||
// Hash returns the hash of the evidence.
|
||||
func (dve *DuplicateVoteEvidence) Bytes() []byte {
|
||||
return cdcEncode(dve)
|
||||
}
|
||||
|
||||
// Hash returns the hash of the evidence.
|
||||
func (dve *DuplicateVoteEvidence) Hash() []byte {
|
||||
return tmhash.Sum(cdcEncode(dve))
|
||||
@ -172,6 +180,8 @@ type MockGoodEvidence struct {
|
||||
Address_ []byte
|
||||
}
|
||||
|
||||
var _ Evidence = &MockGoodEvidence{}
|
||||
|
||||
// UNSTABLE
|
||||
func NewMockGoodEvidence(height int64, idx int, address []byte) MockGoodEvidence {
|
||||
return MockGoodEvidence{height, address}
|
||||
@ -182,6 +192,9 @@ func (e MockGoodEvidence) Address() []byte { return e.Address_ }
|
||||
func (e MockGoodEvidence) Hash() []byte {
|
||||
return []byte(fmt.Sprintf("%d-%x", e.Height_, e.Address_))
|
||||
}
|
||||
func (e MockGoodEvidence) Bytes() []byte {
|
||||
return []byte(fmt.Sprintf("%d-%x", e.Height_, e.Address_))
|
||||
}
|
||||
func (e MockGoodEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil }
|
||||
func (e MockGoodEvidence) Equal(ev Evidence) bool {
|
||||
e2 := ev.(MockGoodEvidence)
|
||||
@ -216,18 +229,14 @@ type EvidenceList []Evidence
|
||||
|
||||
// Hash returns the simple merkle root hash of the EvidenceList.
|
||||
func (evl EvidenceList) Hash() []byte {
|
||||
// Recursive impl.
|
||||
// Copied from crypto/merkle to avoid allocations
|
||||
switch len(evl) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return evl[0].Hash()
|
||||
default:
|
||||
left := EvidenceList(evl[:(len(evl)+1)/2]).Hash()
|
||||
right := EvidenceList(evl[(len(evl)+1)/2:]).Hash()
|
||||
return merkle.SimpleHashFromTwoHashes(left, right)
|
||||
// These allocations are required because Evidence is not of type Bytes, and
|
||||
// golang slices can't be typed cast. This shouldn't be a performance problem since
|
||||
// the Evidence size is capped.
|
||||
evidenceBzs := make([][]byte, len(evl))
|
||||
for i := 0; i < len(evl); i++ {
|
||||
evidenceBzs[i] = evl[i].Bytes()
|
||||
}
|
||||
return merkle.SimpleHashFromByteSlices(evidenceBzs)
|
||||
}
|
||||
|
||||
func (evl EvidenceList) String() string {
|
||||
|
17
types/tx.go
17
types/tx.go
@ -31,18 +31,13 @@ type Txs []Tx
|
||||
|
||||
// Hash returns the simple Merkle root hash of the transactions.
|
||||
func (txs Txs) Hash() []byte {
|
||||
// Recursive impl.
|
||||
// Copied from tendermint/crypto/merkle to avoid allocations
|
||||
switch len(txs) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return txs[0].Hash()
|
||||
default:
|
||||
left := Txs(txs[:(len(txs)+1)/2]).Hash()
|
||||
right := Txs(txs[(len(txs)+1)/2:]).Hash()
|
||||
return merkle.SimpleHashFromTwoHashes(left, right)
|
||||
// These allocations will be removed once Txs is switched to [][]byte,
|
||||
// ref #2603. This is because golang does not allow type casting slices without unsafe
|
||||
txBzs := make([][]byte, len(txs))
|
||||
for i := 0; i < len(txs); i++ {
|
||||
txBzs[i] = txs[i]
|
||||
}
|
||||
return merkle.SimpleHashFromByteSlices(txBzs)
|
||||
}
|
||||
|
||||
// Index returns the index of this transaction in the list, or -1 if not found
|
||||
|
Reference in New Issue
Block a user