Browse Source

evidence: retrieve header at height of evidence for validation (#4870)

validation of lunatic evidence requires that the node retrieve the header at the height of the infringement from the block store for comparison
pull/4945/head
Callum Waters 5 years ago
committed by GitHub
parent
commit
26bea83694
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 5 deletions
  1. +1
    -0
      consensus/reactor_test.go
  2. +1
    -0
      consensus/replay_stubs.go
  3. +13
    -4
      evidence/pool.go
  4. +16
    -0
      state/mocks/evidence_pool.go
  5. +2
    -0
      state/services.go
  6. +10
    -1
      state/validation.go

+ 1
- 0
consensus/reactor_test.go View File

@ -236,6 +236,7 @@ func (m *mockEvidencePool) IsPending(evidence types.Evidence) bool {
return false return false
} }
func (m *mockEvidencePool) AddPOLC(types.ProofOfLockChange) error { return nil } func (m *mockEvidencePool) AddPOLC(types.ProofOfLockChange) error { return nil }
func (m *mockEvidencePool) Header(int64) *types.Header { return nil }
//------------------------------------ //------------------------------------


+ 1
- 0
consensus/replay_stubs.go View File

@ -56,6 +56,7 @@ func (emptyEvidencePool) Update(*types.Block, sm.State) {}
func (emptyEvidencePool) IsCommitted(types.Evidence) bool { return false } func (emptyEvidencePool) IsCommitted(types.Evidence) bool { return false }
func (emptyEvidencePool) IsPending(types.Evidence) bool { return false } func (emptyEvidencePool) IsPending(types.Evidence) bool { return false }
func (emptyEvidencePool) AddPOLC(types.ProofOfLockChange) error { return nil } func (emptyEvidencePool) AddPOLC(types.ProofOfLockChange) error { return nil }
func (emptyEvidencePool) Header(int64) *types.Header { return nil }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// mockProxyApp uses ABCIResponses to give the right results. // mockProxyApp uses ABCIResponses to give the right results.


+ 13
- 4
evidence/pool.go View File

@ -181,11 +181,10 @@ func (evpool *Pool) AddEvidence(evidence types.Evidence) error {
// For lunatic validator evidence, a header needs to be fetched. // For lunatic validator evidence, a header needs to be fetched.
var header *types.Header var header *types.Header
if _, ok := ev.(*types.LunaticValidatorEvidence); ok { if _, ok := ev.(*types.LunaticValidatorEvidence); ok {
blockMeta := evpool.blockStore.LoadBlockMeta(ev.Height())
if blockMeta == nil {
header = evpool.Header(ev.Height())
if header == nil {
return fmt.Errorf("don't have block meta at height #%d", ev.Height()) return fmt.Errorf("don't have block meta at height #%d", ev.Height())
} }
header = &blockMeta.Header
} }
// 1) Verify against state. // 1) Verify against state.
@ -266,7 +265,7 @@ func (evpool *Pool) IsCommitted(evidence types.Evidence) bool {
return ok return ok
} }
// Checks whether the evidence is already pending. DB errors are passed to the logger.
// IsPending checks whether the evidence is already pending. DB errors are passed to the logger.
func (evpool *Pool) IsPending(evidence types.Evidence) bool { func (evpool *Pool) IsPending(evidence types.Evidence) bool {
key := keyPending(evidence) key := keyPending(evidence)
ok, err := evpool.evidenceStore.Has(key) ok, err := evpool.evidenceStore.Has(key)
@ -306,6 +305,16 @@ func (evpool *Pool) SetLogger(l log.Logger) {
evpool.logger = l evpool.logger = l
} }
// Header gets the header from the block store at a specified height.
// Is used for validation of LunaticValidatorEvidence
func (evpool *Pool) Header(height int64) *types.Header {
blockMeta := evpool.blockStore.LoadBlockMeta(height)
if blockMeta == nil {
return nil
}
return &blockMeta.Header
}
// ValidatorLastHeight returns the last height of the validator w/ the // ValidatorLastHeight returns the last height of the validator w/ the
// given address. 0 - if address never was a validator or was such a // given address. 0 - if address never was a validator or was such a
// long time ago (> ConsensusParams.Evidence.MaxAgeDuration && > // long time ago (> ConsensusParams.Evidence.MaxAgeDuration && >


+ 16
- 0
state/mocks/evidence_pool.go View File

@ -28,6 +28,22 @@ func (_m *EvidencePool) AddEvidence(_a0 types.Evidence) error {
return r0 return r0
} }
// Header provides a mock function with given fields: _a0
func (_m *EvidencePool) Header(_a0 int64) *types.Header {
ret := _m.Called(_a0)
var r0 *types.Header
if rf, ok := ret.Get(0).(func(int64) *types.Header); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Header)
}
}
return r0
}
// IsCommitted provides a mock function with given fields: _a0 // IsCommitted provides a mock function with given fields: _a0
func (_m *EvidencePool) IsCommitted(_a0 types.Evidence) bool { func (_m *EvidencePool) IsCommitted(_a0 types.Evidence) bool {
ret := _m.Called(_a0) ret := _m.Called(_a0)


+ 2
- 0
state/services.go View File

@ -45,6 +45,7 @@ type EvidencePool interface {
Update(*types.Block, State) Update(*types.Block, State)
IsCommitted(types.Evidence) bool IsCommitted(types.Evidence) bool
IsPending(types.Evidence) bool IsPending(types.Evidence) bool
Header(int64) *types.Header
} }
// MockEvidencePool is an empty implementation of EvidencePool, useful for testing. // MockEvidencePool is an empty implementation of EvidencePool, useful for testing.
@ -55,3 +56,4 @@ func (me MockEvidencePool) AddEvidence(types.Evidence) error { return nil
func (me MockEvidencePool) Update(*types.Block, State) {} func (me MockEvidencePool) Update(*types.Block, State) {}
func (me MockEvidencePool) IsCommitted(types.Evidence) bool { return false } func (me MockEvidencePool) IsCommitted(types.Evidence) bool { return false }
func (me MockEvidencePool) IsPending(types.Evidence) bool { return false } func (me MockEvidencePool) IsPending(types.Evidence) bool { return false }
func (me MockEvidencePool) Header(int64) *types.Header { return nil }

+ 10
- 1
state/validation.go View File

@ -142,7 +142,16 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
continue continue
} }
} }
if err := VerifyEvidence(stateDB, state, ev, &block.Header); err != nil {
var header *types.Header
if _, ok := ev.(*types.LunaticValidatorEvidence); ok {
header = evidencePool.Header(ev.Height())
if header == nil {
return fmt.Errorf("don't have block meta at height #%d", ev.Height())
}
}
if err := VerifyEvidence(stateDB, state, ev, header); err != nil {
return types.NewErrEvidenceInvalid(ev, err) return types.NewErrEvidenceInvalid(ev, err)
} }
} }


Loading…
Cancel
Save