evidence: both MaxAgeDuration and MaxAgeNumBlocks need to be surpassed (#4667)

for evidence to be considered expired. otherwise, a cabal group can
  manipulate block time to make a particular evidence too old.

Refs https://github.com/tendermint/tendermint/issues/2565#issuecomment-432896645
Refs https://github.com/tendermint/tendermint/issues/2653
spec PR: tendermint/spec#87
This commit is contained in:
Anton Kaliaev
2020-04-14 14:58:50 +04:00
committed by GitHub
parent fb35b474ad
commit 11fa625934
4 changed files with 18 additions and 18 deletions
+1 -2
View File
@@ -163,8 +163,7 @@ func (evpool *Pool) removeEvidence(
// Remove the evidence if it's already in a block or if it's now too old.
if _, ok := blockEvidenceMap[evMapKey(ev)]; ok ||
ageNumBlocks > params.MaxAgeNumBlocks ||
ageDuration > params.MaxAgeDuration {
(ageDuration > params.MaxAgeDuration && ageNumBlocks > params.MaxAgeNumBlocks) {
// remove from clist
evpool.evidenceList.Remove(e)
e.DetachPrev()
+5 -5
View File
@@ -58,7 +58,7 @@ func TestEvidencePool(t *testing.T) {
var (
valAddr = []byte("val1")
height = int64(5)
height = int64(100002)
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
@@ -66,7 +66,7 @@ func TestEvidencePool(t *testing.T) {
)
goodEvidence := types.NewMockEvidence(height, time.Now(), 0, valAddr)
badEvidence := types.NewMockEvidence(height, evidenceTime, 0, valAddr)
badEvidence := types.NewMockEvidence(1, evidenceTime, 0, valAddr)
// bad evidence
err := pool.AddEvidence(badEvidence)
@@ -134,10 +134,10 @@ func TestAddEvidence(t *testing.T) {
evDescription string
}{
{height, time.Now(), false, "valid evidence"},
{height, evidenceTime, true, "evidence created at 2019-01-01 00:00:00 +0000 UTC has expired"},
{int64(1), time.Now(), true, "evidence from height 1 is too old"},
{height, evidenceTime, false, "valid evidence (despite old time)"},
{int64(1), time.Now(), false, "valid evidence (despite old height)"},
{int64(1), evidenceTime, true,
"evidence from height 1 is too old & evidence created at 2019-01-01 00:00:00 +0000 UTC has expired"},
"evidence from height 1 (created at: 2019-01-01 00:00:00 +0000 UTC) is too old"},
}
for _, tc := range testCases {
+1 -1
View File
@@ -194,7 +194,7 @@ func (evR Reactor) checkSendEvidenceMessage(
if peerHeight < evHeight { // peer is behind. sleep while he catches up
return nil, true
} else if ageNumBlocks > params.MaxAgeNumBlocks ||
} else if ageNumBlocks > params.MaxAgeNumBlocks &&
ageDuration > params.MaxAgeDuration { // evidence is too old, skip
// NOTE: if evidence is too old for an honest peer, then we're behind and
+11 -10
View File
@@ -162,18 +162,19 @@ func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error
var (
height = state.LastBlockHeight
evidenceParams = state.ConsensusParams.Evidence
ageDuration = state.LastBlockTime.Sub(evidence.Time())
ageNumBlocks = height - evidence.Height()
)
ageNumBlocks := height - evidence.Height()
if ageNumBlocks > evidenceParams.MaxAgeNumBlocks {
return fmt.Errorf("evidence from height %d is too old. Min height is %d",
evidence.Height(), height-evidenceParams.MaxAgeNumBlocks)
}
ageDuration := state.LastBlockTime.Sub(evidence.Time())
if ageDuration > evidenceParams.MaxAgeDuration {
return fmt.Errorf("evidence created at %v has expired. Evidence can not be older than: %v",
evidence.Time(), state.LastBlockTime.Add(evidenceParams.MaxAgeDuration))
if ageDuration > evidenceParams.MaxAgeDuration && ageNumBlocks > evidenceParams.MaxAgeNumBlocks {
return fmt.Errorf(
"evidence from height %d (created at: %v) is too old; min height is %d and evidence can not be older than %v",
evidence.Height(),
evidence.Time(),
height-evidenceParams.MaxAgeNumBlocks,
state.LastBlockTime.Add(evidenceParams.MaxAgeDuration),
)
}
valset, err := LoadValidators(stateDB, evidence.Height())