You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.2 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package evidence
  2. import (
  3. "fmt"
  4. "sync"
  5. dbm "github.com/tendermint/tmlibs/db"
  6. "github.com/tendermint/tmlibs/log"
  7. sm "github.com/tendermint/tendermint/state"
  8. "github.com/tendermint/tendermint/types"
  9. )
  10. // EvidencePool maintains a pool of valid evidence
  11. // in an EvidenceStore.
  12. type EvidencePool struct {
  13. logger log.Logger
  14. evidenceStore *EvidenceStore
  15. // needed to load validators to verify evidence
  16. stateDB dbm.DB
  17. // latest state
  18. mtx sync.Mutex
  19. state sm.State
  20. // never close
  21. evidenceChan chan types.Evidence
  22. }
  23. func NewEvidencePool(stateDB dbm.DB, evidenceStore *EvidenceStore) *EvidencePool {
  24. evpool := &EvidencePool{
  25. stateDB: stateDB,
  26. state: sm.LoadState(stateDB),
  27. logger: log.NewNopLogger(),
  28. evidenceStore: evidenceStore,
  29. evidenceChan: make(chan types.Evidence),
  30. }
  31. return evpool
  32. }
  33. // SetLogger sets the Logger.
  34. func (evpool *EvidencePool) SetLogger(l log.Logger) {
  35. evpool.logger = l
  36. }
  37. // EvidenceChan returns an unbuffered channel on which new evidence can be received.
  38. func (evpool *EvidencePool) EvidenceChan() <-chan types.Evidence {
  39. return evpool.evidenceChan
  40. }
  41. // PriorityEvidence returns the priority evidence.
  42. func (evpool *EvidencePool) PriorityEvidence() []types.Evidence {
  43. return evpool.evidenceStore.PriorityEvidence()
  44. }
  45. // PendingEvidence returns all uncommitted evidence.
  46. func (evpool *EvidencePool) PendingEvidence() []types.Evidence {
  47. return evpool.evidenceStore.PendingEvidence()
  48. }
  49. // State returns the current state of the evpool.
  50. func (evpool *EvidencePool) State() sm.State {
  51. evpool.mtx.Lock()
  52. defer evpool.mtx.Unlock()
  53. return evpool.state
  54. }
  55. // Update loads the latest
  56. func (evpool *EvidencePool) Update(block *types.Block) {
  57. evpool.mtx.Lock()
  58. defer evpool.mtx.Unlock()
  59. state := sm.LoadState(evpool.stateDB)
  60. if state.LastBlockHeight != block.Height {
  61. panic(fmt.Sprintf("EvidencePool.Update: loaded state with height %d when block.Height=%d", state.LastBlockHeight, block.Height))
  62. }
  63. evpool.state = state
  64. // NOTE: shouldn't need the mutex
  65. evpool.MarkEvidenceAsCommitted(block.Evidence.Evidence)
  66. }
  67. // AddEvidence checks the evidence is valid and adds it to the pool.
  68. // Blocks on the EvidenceChan.
  69. func (evpool *EvidencePool) AddEvidence(evidence types.Evidence) (err error) {
  70. // TODO: check if we already have evidence for this
  71. // validator at this height so we dont get spammed
  72. if err := sm.VerifyEvidence(evpool.stateDB, evpool.State(), evidence); err != nil {
  73. return err
  74. }
  75. // fetch the validator and return its voting power as its priority
  76. // TODO: something better ?
  77. valset, _ := sm.LoadValidators(evpool.stateDB, evidence.Height())
  78. _, val := valset.GetByAddress(evidence.Address())
  79. priority := val.VotingPower
  80. added := evpool.evidenceStore.AddNewEvidence(evidence, priority)
  81. if !added {
  82. // evidence already known, just ignore
  83. return
  84. }
  85. evpool.logger.Info("Verified new evidence of byzantine behaviour", "evidence", evidence)
  86. // never closes. always safe to send on
  87. evpool.evidenceChan <- evidence
  88. return nil
  89. }
  90. // MarkEvidenceAsCommitted marks all the evidence as committed.
  91. func (evpool *EvidencePool) MarkEvidenceAsCommitted(evidence []types.Evidence) {
  92. for _, ev := range evidence {
  93. evpool.evidenceStore.MarkEvidenceAsCommitted(ev)
  94. }
  95. }