cap evidence in block validation

This commit is contained in:
Ethan Buchman 2018-10-05 23:14:28 -04:00
parent dfda7b442f
commit dc0c77bc9e
3 changed files with 31 additions and 8 deletions

View File

@ -26,7 +26,7 @@ BREAKING CHANGES:
* Blockchain Protocol
* [types] \#2459 `Vote`/`Proposal`/`Heartbeat` use amino encoding instead of JSON in `SignBytes`.
* [types] \#2512 Remove the pubkey field from the validator hash
* [types] \#2512 Remove the pubkey field from the validator hash
* P2P Protocol
@ -41,9 +41,11 @@ IMPROVEMENTS:
BUG FIXES:
- [autofile] \#2428 Group.RotateFile need call Flush() before rename (@goolAdapter)
- [node] \#2434 Make node respond to signal interrupts while sleeping for genesis time
- [consensus] [\#1690](https://github.com/tendermint/tendermint/issues/1690) wait for
- [consensus] [\#1690](https://github.com/tendermint/tendermint/issues/1690) wait for
timeoutPrecommit before starting next round
- [evidence] \#2515 fix db iter leak (@goolAdapter)
- [common/bit_array] Fixed a bug in the `Or` function
- [common/bit_array] Fixed a bug in the `Sub` function (@bradyjoestar)
- [common] \#2534 make bit array's PickRandom choose uniformly from true bits
- [common] \#2534 Make bit array's PickRandom choose uniformly from true bits
- [consensus] \#1637 Limit the amount of evidence that can be included in a
block

View File

@ -125,13 +125,17 @@ func validateBlock(stateDB dbm.DB, state State, block *types.Block) error {
}
}
// Limit the amount of evidence
maxEvidenceBytes := types.MaxEvidenceBytesPerBlock(state.ConsensusParams.BlockSize.MaxBytes)
evidenceBytes := int64(len(block.Evidence.Evidence)) * types.MaxEvidenceBytes
if evidenceBytes > maxEvidenceBytes {
return types.NewErrEvidenceOverflow(maxEvidenceBytes, evidenceBytes)
}
// Validate all evidence.
// TODO: Each check requires loading an old validator set.
// We should cap the amount of evidence per block
// to prevent potential proposer DoS.
for _, ev := range block.Evidence.Evidence {
if err := VerifyEvidence(stateDB, state, ev); err != nil {
return types.NewEvidenceInvalidErr(ev, err)
return types.NewErrEvidenceInvalid(ev, err)
}
}

View File

@ -21,7 +21,8 @@ type ErrEvidenceInvalid struct {
ErrorValue error
}
func NewEvidenceInvalidErr(ev Evidence, err error) *ErrEvidenceInvalid {
// NewErrEvidenceInvalid returns a new EvidenceInvalid with the given err.
func NewErrEvidenceInvalid(ev Evidence, err error) *ErrEvidenceInvalid {
return &ErrEvidenceInvalid{ev, err}
}
@ -30,6 +31,22 @@ func (err *ErrEvidenceInvalid) Error() string {
return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.ErrorValue, err.Evidence)
}
// ErrEvidenceOverflow is for when there is too much evidence in a block.
type ErrEvidenceOverflow struct {
MaxBytes int64
GotBytes int64
}
// NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max.
func NewErrEvidenceOverflow(max, got int64) *ErrEvidenceOverflow {
return &ErrEvidenceOverflow{max, got}
}
// Error returns a string representation of the error.
func (err *ErrEvidenceOverflow) Error() string {
return fmt.Sprintf("Too much evidence: Max %d bytes, got %d bytes", err.MaxBytes, err.GotBytes)
}
//-------------------------------------------
// Evidence represents any provable malicious activity by a validator