mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-25 18:51:39 +00:00
types: evidence cleanup
This commit is contained in:
@ -309,7 +309,7 @@ func (s *State) validateBlock(b *types.Block) error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, ev := range block.Evidence.Evidences {
|
||||
for _, ev := range block.Evidence.Evidence {
|
||||
if _, err := s.VerifyEvidence(ev); err != nil {
|
||||
return types.NewEvidenceInvalidErr(ev, err)
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ func (s *State) GetValidators() (last *types.ValidatorSet, current *types.Valida
|
||||
// VerifyEvidence verifies the evidence fully by checking it is internally
|
||||
// consistent and corresponds to an existing or previous validator.
|
||||
// It returns the priority of this evidence, or an error.
|
||||
// NOTE: return error may be ErrLoadValidators, in which case the validator set
|
||||
// NOTE: return error may be ErrNoValSetForHeight, in which case the validator set
|
||||
// for the evidence height could not be loaded.
|
||||
func (s *State) VerifyEvidence(evidence types.Evidence) (priority int, err error) {
|
||||
if err := evidence.Verify(s.ChainID); err != nil {
|
||||
|
@ -43,7 +43,7 @@ func MakeBlock(height int64, txs []Tx, commit *Commit) *Block {
|
||||
|
||||
// AddEvidence appends the given evidence to the block
|
||||
func (b *Block) AddEvidence(evidence []Evidence) {
|
||||
b.Evidence.Evidences = append(b.Evidence.Evidences, evidence...)
|
||||
b.Evidence.Evidence = append(b.Evidence.Evidence, evidence...)
|
||||
}
|
||||
|
||||
// ValidateBasic performs basic validation that doesn't involve state data.
|
||||
@ -437,8 +437,7 @@ func (data *Data) StringIndented(indent string) string {
|
||||
|
||||
// EvidenceData contains any evidence of malicious wrong-doing by validators
|
||||
type EvidenceData struct {
|
||||
// TODO: FIXME
|
||||
Evidences evidences `json:"evidence"`
|
||||
Evidence EvidenceList `json:"evidence"`
|
||||
|
||||
// Volatile
|
||||
hash data.Bytes
|
||||
@ -447,7 +446,7 @@ type EvidenceData struct {
|
||||
// Hash returns the hash of the data.
|
||||
func (data *EvidenceData) Hash() data.Bytes {
|
||||
if data.hash == nil {
|
||||
data.hash = data.Evidences.Hash()
|
||||
data.hash = data.Evidence.Hash()
|
||||
}
|
||||
return data.hash
|
||||
}
|
||||
@ -457,10 +456,10 @@ func (data *EvidenceData) StringIndented(indent string) string {
|
||||
if data == nil {
|
||||
return "nil-Evidence"
|
||||
}
|
||||
evStrings := make([]string, cmn.MinInt(len(data.Evidences), 21))
|
||||
for i, ev := range data.Evidences {
|
||||
evStrings := make([]string, cmn.MinInt(len(data.Evidence), 21))
|
||||
for i, ev := range data.Evidence {
|
||||
if i == 20 {
|
||||
evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidences))
|
||||
evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidence))
|
||||
break
|
||||
}
|
||||
evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
|
||||
|
@ -3,7 +3,6 @@ package types
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/tmlibs/merkle"
|
||||
@ -26,10 +25,6 @@ func (err *ErrEvidenceInvalid) Error() string {
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
type HistoricalValidators interface {
|
||||
LoadValidators(height int) (*ValidatorSet, error)
|
||||
}
|
||||
|
||||
// Evidence represents any provable malicious activity by a validator
|
||||
type Evidence interface {
|
||||
Height() int // height of the equivocation
|
||||
@ -44,96 +39,36 @@ type Evidence interface {
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
//EvidenceSet is a thread-safe set of evidence.
|
||||
type EvidenceSet struct {
|
||||
sync.RWMutex
|
||||
evidences evidences
|
||||
}
|
||||
// EvidenceList is a list of Evidence. Evidences is not a word.
|
||||
type EvidenceList []Evidence
|
||||
|
||||
//Evidence returns a copy of all the evidence.
|
||||
func (evset EvidenceSet) Evidence() []Evidence {
|
||||
evset.RLock()
|
||||
defer evset.RUnlock()
|
||||
evCopy := make([]Evidence, len(evset.evidences))
|
||||
for i, ev := range evset.evidences {
|
||||
evCopy[i] = ev
|
||||
}
|
||||
return evCopy
|
||||
}
|
||||
|
||||
// Size returns the number of pieces of evidence in the set.
|
||||
func (evset EvidenceSet) Size() int {
|
||||
evset.RLock()
|
||||
defer evset.RUnlock()
|
||||
return len(evset.evidences)
|
||||
}
|
||||
|
||||
// Hash returns a merkle hash of the evidence.
|
||||
func (evset EvidenceSet) Hash() []byte {
|
||||
evset.RLock()
|
||||
defer evset.RUnlock()
|
||||
return evset.evidences.Hash()
|
||||
}
|
||||
|
||||
// Has returns true if the given evidence is in the set.
|
||||
func (evset EvidenceSet) Has(evidence Evidence) bool {
|
||||
evset.RLock()
|
||||
defer evset.RUnlock()
|
||||
return evset.evidences.Has(evidence)
|
||||
}
|
||||
|
||||
// String returns a string representation of the evidence.
|
||||
func (evset EvidenceSet) String() string {
|
||||
evset.RLock()
|
||||
defer evset.RUnlock()
|
||||
return evset.evidences.String()
|
||||
}
|
||||
|
||||
// Add adds the given evidence to the set.
|
||||
// TODO: and persists it to disk.
|
||||
func (evset EvidenceSet) Add(evidence Evidence) {
|
||||
evset.Lock()
|
||||
defer evset.Unlock()
|
||||
evset.evidences = append(evset.evidences, evidence)
|
||||
}
|
||||
|
||||
// Reset empties the evidence set.
|
||||
func (evset EvidenceSet) Reset() {
|
||||
evset.Lock()
|
||||
defer evset.Unlock()
|
||||
evset.evidences = make(evidences, 0)
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
type evidences []Evidence
|
||||
|
||||
func (evs evidences) Hash() []byte {
|
||||
// Hash returns the simple merkle root hash of the EvidenceList.
|
||||
func (evl EvidenceList) Hash() []byte {
|
||||
// Recursive impl.
|
||||
// Copied from tmlibs/merkle to avoid allocations
|
||||
switch len(evs) {
|
||||
switch len(evl) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return evs[0].Hash()
|
||||
return evl[0].Hash()
|
||||
default:
|
||||
left := evidences(evs[:(len(evs)+1)/2]).Hash()
|
||||
right := evidences(evs[(len(evs)+1)/2:]).Hash()
|
||||
left := EvidenceList(evl[:(len(evl)+1)/2]).Hash()
|
||||
right := EvidenceList(evl[(len(evl)+1)/2:]).Hash()
|
||||
return merkle.SimpleHashFromTwoHashes(left, right)
|
||||
}
|
||||
}
|
||||
|
||||
func (evs evidences) String() string {
|
||||
func (evl EvidenceList) String() string {
|
||||
s := ""
|
||||
for _, e := range evs {
|
||||
for _, e := range evl {
|
||||
s += fmt.Sprintf("%s\t\t", e)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (evs evidences) Has(evidence Evidence) bool {
|
||||
for _, ev := range evs {
|
||||
// Has returns true if the evidence is in the EvidenceList.
|
||||
func (evl EvidenceList) Has(evidence Evidence) bool {
|
||||
for _, ev := range evl {
|
||||
if ev.Equal(evidence) {
|
||||
return true
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
abci "github.com/tendermint/abci/types"
|
||||
)
|
||||
|
||||
// NOTE: all types in this file are considered UNSTABLE
|
||||
// NOTE/XXX: all type definitions in this file are considered UNSTABLE
|
||||
|
||||
//------------------------------------------------------
|
||||
// blockchain services types
|
||||
@ -73,6 +73,8 @@ type BlockStore interface {
|
||||
//------------------------------------------------------
|
||||
// state
|
||||
|
||||
// State defines the stateful interface used to verify evidence.
|
||||
// UNSTABLE
|
||||
type State interface {
|
||||
VerifyEvidence(Evidence) (priority int, err error)
|
||||
}
|
||||
|
Reference in New Issue
Block a user