types: Evidences for merkle hashing; Evidence.String()

This commit is contained in:
Ethan Buchman
2017-08-28 20:01:34 -04:00
parent 9cdcffbe4b
commit 77e45756f2
3 changed files with 57 additions and 9 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/tendermint/go-crypto"
"github.com/tendermint/tmlibs/merkle"
)
// ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid.
@@ -22,10 +23,34 @@ func (err *ErrEvidenceInvalid) Error() string {
return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.ErrorValue, err.Evidence)
}
//-------------------------------------------
// Evidence represents any provable malicious activity by a validator
type Evidence interface {
Verify(chainID string) error
Address() []byte
Hash() []byte
Verify(chainID string) error
String() string
}
//-------------------------------------------
type Evidences []Evidence
func (evs Evidences) Hash() []byte {
// Recursive impl.
// Copied from tmlibs/merkle to avoid allocations
switch len(evs) {
case 0:
return nil
case 1:
return evs[0].Hash()
default:
left := Evidences(evs[:(len(evs)+1)/2]).Hash()
right := Evidences(evs[(len(evs)+1)/2:]).Hash()
return merkle.SimpleHashFromTwoHashes(left, right)
}
}
//-------------------------------------------
@@ -37,11 +62,22 @@ type DuplicateVoteEvidence struct {
VoteB *Vote
}
// String returns a string representation of the evidence.
func (dve *DuplicateVoteEvidence) String() string {
return fmt.Sprintf("VoteA: %v; VoteB: %v", dve.VoteA, dve.VoteB)
}
// Address returns the address of the validator.
func (dve *DuplicateVoteEvidence) Address() []byte {
return dve.PubKey.Address()
}
// Hash returns the hash of the evidence.
func (dve *DuplicateVoteEvidence) Hash() []byte {
return merkle.SimpleHashFromBinary(dve)
}
// Verify returns an error if the two votes aren't conflicting.
// To be conflicting, they must be from the same validator, for the same H/R/S, but for different blocks.
func (dve *DuplicateVoteEvidence) Verify(chainID string) error {