From 7a18fa887d4bc984141357994a113ec11e686f1e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 19 Nov 2017 02:02:58 +0000 Subject: [PATCH] evidence linked with consensus/node. compiles --- consensus/common_test.go | 5 ++++- consensus/replay_file.go | 6 ++++-- consensus/state.go | 9 +++++---- evidence/evidence_pool.go | 19 +++++++++++++------ evidence/store.go | 19 ++++--------------- node/node.go | 31 +++++++++++++++++++++++++++---- rpc/core/pipe.go | 5 +++++ types/services.go | 4 ++-- 8 files changed, 64 insertions(+), 34 deletions(-) diff --git a/consensus/common_test.go b/consensus/common_test.go index dd6fce660..6598c15eb 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -260,8 +260,11 @@ func newConsensusStateWithConfigAndBlockStore(thisConfig *cfg.Config, state *sm. mempool.EnableTxsAvailable() } + // mock the evidence pool + evpool := types.MockEvidencePool{} + // Make ConsensusReactor - cs := NewConsensusState(thisConfig.Consensus, state, proxyAppConnCon, blockStore, mempool) + cs := NewConsensusState(thisConfig.Consensus, state, proxyAppConnCon, blockStore, mempool, evpool) cs.SetLogger(log.TestingLogger()) cs.SetPrivValidator(pv) diff --git a/consensus/replay_file.go b/consensus/replay_file.go index d291e87c4..4db58ada8 100644 --- a/consensus/replay_file.go +++ b/consensus/replay_file.go @@ -123,7 +123,8 @@ func (pb *playback) replayReset(count int, newStepCh chan interface{}) error { pb.cs.Stop() pb.cs.Wait() - newCS := NewConsensusState(pb.cs.config, pb.genesisState.Copy(), pb.cs.proxyAppConn, pb.cs.blockStore, pb.cs.mempool) + newCS := NewConsensusState(pb.cs.config, pb.genesisState.Copy(), pb.cs.proxyAppConn, + pb.cs.blockStore, pb.cs.mempool, pb.cs.evpool) newCS.SetEventBus(pb.cs.eventBus) newCS.startForReplay() @@ -302,7 +303,8 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusCo cmn.Exit(cmn.Fmt("Failed to start event bus: %v", err)) } - consensusState := NewConsensusState(csConfig, state.Copy(), proxyApp.Consensus(), blockStore, types.MockMempool{}) + consensusState := NewConsensusState(csConfig, state.Copy(), proxyApp.Consensus(), + blockStore, types.MockMempool{}, types.MockEvidencePool{}) consensusState.SetEventBus(eventBus) return consensusState diff --git a/consensus/state.go b/consensus/state.go index 99bc4809b..7531f1975 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -17,7 +17,6 @@ import ( cfg "github.com/tendermint/tendermint/config" cstypes "github.com/tendermint/tendermint/consensus/types" - evpool "github.com/tendermint/tendermint/evidence" "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" @@ -79,7 +78,7 @@ type ConsensusState struct { proxyAppConn proxy.AppConnConsensus blockStore types.BlockStore mempool types.Mempool - evpool evpool.EvidencePool + evpool types.EvidencePool // internal state mtx sync.Mutex @@ -115,7 +114,7 @@ type ConsensusState struct { } // NewConsensusState returns a new ConsensusState. -func NewConsensusState(config *cfg.ConsensusConfig, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState { +func NewConsensusState(config *cfg.ConsensusConfig, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool, evpool types.EvidencePool) *ConsensusState { cs := &ConsensusState{ config: config, proxyAppConn: proxyAppConn, @@ -127,7 +126,7 @@ func NewConsensusState(config *cfg.ConsensusConfig, state *sm.State, proxyAppCon done: make(chan struct{}), doWALCatchup: true, wal: nilWAL{}, - // evpool: evpool, + evpool: evpool, } // set function defaults (may be overwritten before calling Start) cs.decideProposal = cs.defaultDecideProposal @@ -1237,6 +1236,8 @@ func (cs *ConsensusState) finalizeCommit(height int64) { fail.Fail() // XXX + // TODO: cs.evpool.Update() + // NewHeightStep! cs.updateToState(stateCopy) diff --git a/evidence/evidence_pool.go b/evidence/evidence_pool.go index cc9e01e7f..41f51ee97 100644 --- a/evidence/evidence_pool.go +++ b/evidence/evidence_pool.go @@ -3,27 +3,28 @@ package evpool import ( "github.com/tendermint/tmlibs/log" + cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/types" ) // EvidencePool maintains a pool of valid evidence // in an EvidenceStore. type EvidencePool struct { - config *EvidencePoolConfig + config *cfg.EvidenceConfig logger log.Logger + state types.State evidenceStore *EvidenceStore - evidenceChan chan types.Evidence -} -type EvidencePoolConfig struct { + evidenceChan chan types.Evidence } -func NewEvidencePool(config *EvidencePoolConfig, evidenceStore *EvidenceStore) *EvidencePool { +func NewEvidencePool(config *cfg.EvidenceConfig, evidenceStore *EvidenceStore, state types.State) *EvidencePool { evpool := &EvidencePool{ config: config, logger: log.NewNopLogger(), evidenceStore: evidenceStore, + state: state, evidenceChan: make(chan types.Evidence), } return evpool @@ -52,7 +53,13 @@ func (evpool *EvidencePool) PendingEvidence() []types.Evidence { // AddEvidence checks the evidence is valid and adds it to the pool. // Blocks on the EvidenceChan. func (evpool *EvidencePool) AddEvidence(evidence types.Evidence) (err error) { - added, err := evpool.evidenceStore.AddNewEvidence(evidence) + + priority, err := evpool.state.VerifyEvidence(evidence) + if err != nil { + return err + } + + added, err := evpool.evidenceStore.AddNewEvidence(evidence, priority) if err != nil { return err } else if !added { diff --git a/evidence/store.go b/evidence/store.go index 0748a7217..e186aea5b 100644 --- a/evidence/store.go +++ b/evidence/store.go @@ -51,18 +51,12 @@ func _key(key string, evidence types.Evidence) []byte { // evidence that has been committed, evidence that has been seen but not broadcast, // and evidence that has been broadcast but not yet committed. type EvidenceStore struct { - chainID string - db dbm.DB - - // so we can verify evidence was from a real validator - state types.State + db dbm.DB } -func NewEvidenceStore(chainID string, db dbm.DB, state types.State) *EvidenceStore { +func NewEvidenceStore(db dbm.DB) *EvidenceStore { return &EvidenceStore{ - chainID: chainID, - db: db, - state: state, + db: db, } } @@ -93,7 +87,7 @@ func (store *EvidenceStore) PendingEvidence() (evidence []types.Evidence) { } // AddNewEvidence adds the given evidence to the database. -func (store *EvidenceStore) AddNewEvidence(evidence types.Evidence) (bool, error) { +func (store *EvidenceStore) AddNewEvidence(evidence types.Evidence, priority int) (bool, error) { // check if we already have seen it key := keyLookup(evidence) v := store.db.Get(key) @@ -101,11 +95,6 @@ func (store *EvidenceStore) AddNewEvidence(evidence types.Evidence) (bool, error return false, nil } - priority, err := store.state.VerifyEvidence(evidence) - if err != nil { - return false, err - } - ei := evidenceInfo{ Committed: false, Priority: priority, diff --git a/node/node.go b/node/node.go index 352c13ccc..0d20df66b 100644 --- a/node/node.go +++ b/node/node.go @@ -19,6 +19,7 @@ import ( bc "github.com/tendermint/tendermint/blockchain" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/consensus" + evidence "github.com/tendermint/tendermint/evidence" mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p/trust" @@ -107,6 +108,7 @@ type Node struct { mempoolReactor *mempl.MempoolReactor // for gossipping transactions consensusState *consensus.ConsensusState // latest consensus state consensusReactor *consensus.ConsensusReactor // for participating in the consensus + evidencePool *evidence.EvidencePool // tracking evidence proxyApp proxy.AppConns // connection to the application rpcListeners []net.Listener // rpc servers txIndexer txindex.TxIndexer @@ -128,9 +130,6 @@ func NewNode(config *cfg.Config, } blockStore := bc.NewBlockStore(blockStoreDB) - consensusLogger := logger.With("module", "consensus") - stateLogger := logger.With("module", "state") - // Get State stateDB, err := dbProvider(&DBContext{"state", config}) if err != nil { @@ -149,6 +148,7 @@ func NewNode(config *cfg.Config, saveGenesisDoc(stateDB, genDoc) } + stateLogger := logger.With("module", "state") state := sm.LoadState(stateDB) if state == nil { state, err = sm.MakeGenesisState(stateDB, genDoc) @@ -161,6 +161,7 @@ func NewNode(config *cfg.Config, // Create the proxyApp, which manages connections (consensus, mempool, query) // and sync tendermint and the app by replaying any necessary blocks + consensusLogger := logger.With("module", "consensus") handshaker := consensus.NewHandshaker(state, blockStore) handshaker.SetLogger(consensusLogger) proxyApp := proxy.NewAppConns(clientCreator, handshaker) @@ -208,8 +209,22 @@ func NewNode(config *cfg.Config, mempool.EnableTxsAvailable() } + // Make Evidence Reactor + evidenceConfig := &cfg.EvidenceConfig{} // TODO + evidenceDB, err := dbProvider(&DBContext{"evidence", config}) + if err != nil { + return nil, err + } + evidenceLogger := logger.With("module", "evidence") + evidenceStore := evidence.NewEvidenceStore(evidenceDB) + evidencePool := evidence.NewEvidencePool(evidenceConfig, evidenceStore, state) + evidencePool.SetLogger(evidenceLogger) + evidenceReactor := evidence.NewEvidenceReactor(evidenceConfig, evidencePool) + evidenceReactor.SetLogger(evidenceLogger) + // Make ConsensusReactor - consensusState := consensus.NewConsensusState(config.Consensus, state.Copy(), proxyApp.Consensus(), blockStore, mempool) + consensusState := consensus.NewConsensusState(config.Consensus, state.Copy(), + proxyApp.Consensus(), blockStore, mempool, evidencePool) consensusState.SetLogger(consensusLogger) if privValidator != nil { consensusState.SetPrivValidator(privValidator) @@ -224,6 +239,7 @@ func NewNode(config *cfg.Config, sw.AddReactor("MEMPOOL", mempoolReactor) sw.AddReactor("BLOCKCHAIN", bcReactor) sw.AddReactor("CONSENSUS", consensusReactor) + sw.AddReactor("EVIDENCE", evidenceReactor) // Optionally, start the pex reactor var addrBook *p2p.AddrBook @@ -323,6 +339,7 @@ func NewNode(config *cfg.Config, mempoolReactor: mempoolReactor, consensusState: consensusState, consensusReactor: consensusReactor, + evidencePool: evidencePool, proxyApp: proxyApp, txIndexer: txIndexer, indexerService: indexerService, @@ -416,6 +433,7 @@ func (n *Node) ConfigureRPC() { rpccore.SetBlockStore(n.blockStore) rpccore.SetConsensusState(n.consensusState) rpccore.SetMempool(n.mempoolReactor.Mempool) + rpccore.SetEvidencePool(n.evidencePool) rpccore.SetSwitch(n.sw) rpccore.SetPubKey(n.privValidator.GetPubKey()) rpccore.SetGenesisDoc(n.genesisDoc) @@ -489,6 +507,11 @@ func (n *Node) MempoolReactor() *mempl.MempoolReactor { return n.mempoolReactor } +// EvidencePool returns the Node's EvidencePool. +func (n *Node) EvidencePool() *evidence.EvidencePool { + return n.evidencePool +} + // EventBus returns the Node's EventBus. func (n *Node) EventBus() *types.EventBus { return n.eventBus diff --git a/rpc/core/pipe.go b/rpc/core/pipe.go index d0b0f87d3..325625c79 100644 --- a/rpc/core/pipe.go +++ b/rpc/core/pipe.go @@ -45,6 +45,7 @@ var ( // interfaces defined in types and above blockStore types.BlockStore mempool types.Mempool + evidencePool types.EvidencePool consensusState Consensus p2pSwitch P2P @@ -67,6 +68,10 @@ func SetMempool(mem types.Mempool) { mempool = mem } +func SetEvidencePool(evpool types.EvidencePool) { + evidencePool = evpool +} + func SetConsensusState(cs Consensus) { consensusState = cs } diff --git a/types/services.go b/types/services.go index f1d8ddd59..25f77405b 100644 --- a/types/services.go +++ b/types/services.go @@ -84,7 +84,7 @@ type State interface { // UNSTABLE type EvidencePool interface { PendingEvidence() []Evidence - AddEvidence(Evidence) + AddEvidence(Evidence) error } // MockMempool is an empty implementation of a Mempool, useful for testing. @@ -93,4 +93,4 @@ type MockEvidencePool struct { } func (m MockEvidencePool) PendingEvidence() []Evidence { return nil } -func (m MockEvidencePool) AddEvidence(Evidence) {} +func (m MockEvidencePool) AddEvidence(Evidence) error { return nil }