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 {
|
if _, err := s.VerifyEvidence(ev); err != nil {
|
||||||
return types.NewEvidenceInvalidErr(ev, err)
|
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
|
// VerifyEvidence verifies the evidence fully by checking it is internally
|
||||||
// consistent and corresponds to an existing or previous validator.
|
// consistent and corresponds to an existing or previous validator.
|
||||||
// It returns the priority of this evidence, or an error.
|
// 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.
|
// for the evidence height could not be loaded.
|
||||||
func (s *State) VerifyEvidence(evidence types.Evidence) (priority int, err error) {
|
func (s *State) VerifyEvidence(evidence types.Evidence) (priority int, err error) {
|
||||||
if err := evidence.Verify(s.ChainID); err != nil {
|
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
|
// AddEvidence appends the given evidence to the block
|
||||||
func (b *Block) AddEvidence(evidence []Evidence) {
|
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.
|
// 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
|
// EvidenceData contains any evidence of malicious wrong-doing by validators
|
||||||
type EvidenceData struct {
|
type EvidenceData struct {
|
||||||
// TODO: FIXME
|
Evidence EvidenceList `json:"evidence"`
|
||||||
Evidences evidences `json:"evidence"`
|
|
||||||
|
|
||||||
// Volatile
|
// Volatile
|
||||||
hash data.Bytes
|
hash data.Bytes
|
||||||
@ -447,7 +446,7 @@ type EvidenceData struct {
|
|||||||
// Hash returns the hash of the data.
|
// Hash returns the hash of the data.
|
||||||
func (data *EvidenceData) Hash() data.Bytes {
|
func (data *EvidenceData) Hash() data.Bytes {
|
||||||
if data.hash == nil {
|
if data.hash == nil {
|
||||||
data.hash = data.Evidences.Hash()
|
data.hash = data.Evidence.Hash()
|
||||||
}
|
}
|
||||||
return data.hash
|
return data.hash
|
||||||
}
|
}
|
||||||
@ -457,10 +456,10 @@ func (data *EvidenceData) StringIndented(indent string) string {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
return "nil-Evidence"
|
return "nil-Evidence"
|
||||||
}
|
}
|
||||||
evStrings := make([]string, cmn.MinInt(len(data.Evidences), 21))
|
evStrings := make([]string, cmn.MinInt(len(data.Evidence), 21))
|
||||||
for i, ev := range data.Evidences {
|
for i, ev := range data.Evidence {
|
||||||
if i == 20 {
|
if i == 20 {
|
||||||
evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidences))
|
evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidence))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
|
evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
|
||||||
|
@ -3,7 +3,6 @@ package types
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/tendermint/go-crypto"
|
"github.com/tendermint/go-crypto"
|
||||||
"github.com/tendermint/tmlibs/merkle"
|
"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
|
// Evidence represents any provable malicious activity by a validator
|
||||||
type Evidence interface {
|
type Evidence interface {
|
||||||
Height() int // height of the equivocation
|
Height() int // height of the equivocation
|
||||||
@ -44,96 +39,36 @@ type Evidence interface {
|
|||||||
|
|
||||||
//-------------------------------------------
|
//-------------------------------------------
|
||||||
|
|
||||||
//EvidenceSet is a thread-safe set of evidence.
|
// EvidenceList is a list of Evidence. Evidences is not a word.
|
||||||
type EvidenceSet struct {
|
type EvidenceList []Evidence
|
||||||
sync.RWMutex
|
|
||||||
evidences evidences
|
|
||||||
}
|
|
||||||
|
|
||||||
//Evidence returns a copy of all the evidence.
|
// Hash returns the simple merkle root hash of the EvidenceList.
|
||||||
func (evset EvidenceSet) Evidence() []Evidence {
|
func (evl EvidenceList) Hash() []byte {
|
||||||
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 {
|
|
||||||
// Recursive impl.
|
// Recursive impl.
|
||||||
// Copied from tmlibs/merkle to avoid allocations
|
// Copied from tmlibs/merkle to avoid allocations
|
||||||
switch len(evs) {
|
switch len(evl) {
|
||||||
case 0:
|
case 0:
|
||||||
return nil
|
return nil
|
||||||
case 1:
|
case 1:
|
||||||
return evs[0].Hash()
|
return evl[0].Hash()
|
||||||
default:
|
default:
|
||||||
left := evidences(evs[:(len(evs)+1)/2]).Hash()
|
left := EvidenceList(evl[:(len(evl)+1)/2]).Hash()
|
||||||
right := evidences(evs[(len(evs)+1)/2:]).Hash()
|
right := EvidenceList(evl[(len(evl)+1)/2:]).Hash()
|
||||||
return merkle.SimpleHashFromTwoHashes(left, right)
|
return merkle.SimpleHashFromTwoHashes(left, right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (evs evidences) String() string {
|
func (evl EvidenceList) String() string {
|
||||||
s := ""
|
s := ""
|
||||||
for _, e := range evs {
|
for _, e := range evl {
|
||||||
s += fmt.Sprintf("%s\t\t", e)
|
s += fmt.Sprintf("%s\t\t", e)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (evs evidences) Has(evidence Evidence) bool {
|
// Has returns true if the evidence is in the EvidenceList.
|
||||||
for _, ev := range evs {
|
func (evl EvidenceList) Has(evidence Evidence) bool {
|
||||||
|
for _, ev := range evl {
|
||||||
if ev.Equal(evidence) {
|
if ev.Equal(evidence) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
abci "github.com/tendermint/abci/types"
|
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
|
// blockchain services types
|
||||||
@ -73,6 +73,8 @@ type BlockStore interface {
|
|||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
// state
|
// state
|
||||||
|
|
||||||
|
// State defines the stateful interface used to verify evidence.
|
||||||
|
// UNSTABLE
|
||||||
type State interface {
|
type State interface {
|
||||||
VerifyEvidence(Evidence) (priority int, err error)
|
VerifyEvidence(Evidence) (priority int, err error)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user