fix EvidencePool and VerifyEvidence

This commit is contained in:
Ethan Buchman
2017-12-28 23:15:54 -05:00
parent 6112578d07
commit cb845ebff5
8 changed files with 134 additions and 73 deletions
+5 -3
View File
@@ -107,6 +107,11 @@ func (blockExec *BlockExecutor) ApplyBlock(s State, blockID types.BlockID, block
fail.Fail() // XXX
// Update evpool now that state is saved
// TODO: handle the crash/recover scenario
// ie. (may need to call Update for last block)
blockExec.evpool.Update(block)
// events are fired after everything else
// NOTE: if we crash between Commit and Save, events wont be fired during replay
fireEvents(blockExec.logger, blockExec.eventBus, block, abciResponses)
@@ -138,9 +143,6 @@ func (blockExec *BlockExecutor) Commit(block *types.Block) ([]byte, error) {
blockExec.logger.Info("Committed state", "height", block.Height, "txs", block.NumTxs, "appHash", res.Data)
// Update evpool
blockExec.evpool.MarkEvidenceAsCommitted(block.Evidence.Evidence)
// Update mempool.
if err := blockExec.mempool.Update(block.Height, block.Txs); err != nil {
return nil, err
+12 -22
View File
@@ -79,20 +79,9 @@ func validateBlock(stateDB dbm.DB, s State, b *types.Block) error {
}
for _, ev := range b.Evidence.Evidence {
if err := VerifyEvidence(s, ev); err != nil {
if err := VerifyEvidence(stateDB, s, ev); err != nil {
return types.NewEvidenceInvalidErr(ev, err)
}
/* // Needs a db ...
valset, err := LoadValidators(s.db, ev.Height())
if err != nil {
// XXX/TODO: what do we do if we can't load the valset?
// eg. if we have pruned the state or height is too high?
return err
}
if err := VerifyEvidenceValidator(valSet, ev); err != nil {
return types.NewEvidenceInvalidErr(ev, err)
}
*/
}
return nil
@@ -103,7 +92,7 @@ func validateBlock(stateDB dbm.DB, s State, b *types.Block) error {
// VerifyEvidence verifies the evidence fully by checking it is internally
// consistent and sufficiently recent.
func VerifyEvidence(s State, evidence types.Evidence) error {
func VerifyEvidence(stateDB dbm.DB, s State, evidence types.Evidence) error {
height := s.LastBlockHeight
evidenceAge := height - evidence.Height()
@@ -116,22 +105,23 @@ func VerifyEvidence(s State, evidence types.Evidence) error {
if err := evidence.Verify(s.ChainID); err != nil {
return err
}
return nil
}
// VerifyEvidenceValidator returns the voting power of the validator at the height of the evidence.
// It returns an error if the validator did not exist or does not match that loaded from the historical validator set.
func VerifyEvidenceValidator(valset *types.ValidatorSet, evidence types.Evidence) (priority int64, err error) {
valset, err := LoadValidators(stateDB, evidence.Height())
if err != nil {
// TODO: if err is just that we cant find it cuz we pruned, ignore.
// TODO: if its actually bad evidence, punish peer
return err
}
// The address must have been an active validator at the height
ev := evidence
height, addr, idx := ev.Height(), ev.Address(), ev.Index()
valIdx, val := valset.GetByAddress(addr)
if val == nil {
return priority, fmt.Errorf("Address %X was not a validator at height %d", addr, height)
return fmt.Errorf("Address %X was not a validator at height %d", addr, height)
} else if idx != valIdx {
return priority, fmt.Errorf("Address %X was validator %d at height %d, not %d", addr, valIdx, height, idx)
return fmt.Errorf("Address %X was validator %d at height %d, not %d", addr, valIdx, height, idx)
}
priority = val.VotingPower
return priority, nil
return nil
}
+14 -10
View File
@@ -4,61 +4,65 @@ import (
"testing"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
)
func _TestValidateBlock(t *testing.T) {
func TestValidateBlock(t *testing.T) {
state := state()
blockExec := NewBlockExecutor(dbm.NewMemDB(), log.TestingLogger(), nil, nil, nil)
// proper block must pass
block := makeBlock(state, 1)
err := ValidateBlock(state, block)
err := blockExec.ValidateBlock(state, block)
require.NoError(t, err)
// wrong chain fails
block = makeBlock(state, 1)
block.ChainID = "not-the-real-one"
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong height fails
block = makeBlock(state, 1)
block.Height += 10
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong total tx fails
block = makeBlock(state, 1)
block.TotalTxs += 10
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong blockid fails
block = makeBlock(state, 1)
block.LastBlockID.PartsHeader.Total += 10
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong app hash fails
block = makeBlock(state, 1)
block.AppHash = []byte("wrong app hash")
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong consensus hash fails
block = makeBlock(state, 1)
block.ConsensusHash = []byte("wrong consensus hash")
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong results hash fails
block = makeBlock(state, 1)
block.LastResultsHash = []byte("wrong results hash")
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
// wrong validators hash fails
block = makeBlock(state, 1)
block.ValidatorsHash = []byte("wrong validators hash")
err = ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err)
}