diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e05cdc70a5..9064b21d8a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -905,7 +905,7 @@ var ( VotingEnabledFlag = cli.BoolFlag{ Name: "vote", - Usage: "Enable voting", + Usage: "Enable voting when mining", } EnableMaliciousVoteMonitorFlag = cli.BoolFlag{ diff --git a/core/vote/vote_manager.go b/core/vote/vote_manager.go index d50b6d66f1..dcab5c38dd 100644 --- a/core/vote/vote_manager.go +++ b/core/vote/vote_manager.go @@ -16,9 +16,15 @@ import ( var votesManagerCounter = metrics.NewRegisteredCounter("votesManager/local", nil) +// Backend wraps all methods required for voting. +type Backend interface { + IsMining() bool + EventMux() *event.TypeMux +} + // VoteManager will handle the vote produced by self. type VoteManager struct { - mux *event.TypeMux + eth Backend chain *core.BlockChain chainconfig *params.ChainConfig @@ -33,9 +39,9 @@ type VoteManager struct { engine consensus.PoSA } -func NewVoteManager(mux *event.TypeMux, chainconfig *params.ChainConfig, chain *core.BlockChain, pool *VotePool, journalPath, blsPasswordPath, blsWalletPath string, engine consensus.PoSA) (*VoteManager, error) { +func NewVoteManager(eth Backend, chainconfig *params.ChainConfig, chain *core.BlockChain, pool *VotePool, journalPath, blsPasswordPath, blsWalletPath string, engine consensus.PoSA) (*VoteManager, error) { voteManager := &VoteManager{ - mux: mux, + eth: eth, chain: chain, chainconfig: chainconfig, @@ -71,7 +77,7 @@ func NewVoteManager(mux *event.TypeMux, chainconfig *params.ChainConfig, chain * func (voteManager *VoteManager) loop() { log.Debug("vote manager routine loop started") - events := voteManager.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) + events := voteManager.eth.EventMux().Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) defer func() { log.Debug("vote manager loop defer func occur") if !events.Closed() { @@ -106,6 +112,10 @@ func (voteManager *VoteManager) loop() { log.Debug("startVote flag is false, continue") continue } + if !voteManager.eth.IsMining() { + log.Debug("skip voting because mining is disabled, continue") + continue + } if cHead.Block == nil { log.Debug("cHead.Block is nil, continue") diff --git a/core/vote/vote_pool_test.go b/core/vote/vote_pool_test.go index e9daa4ef29..5636bcafea 100644 --- a/core/vote/vote_pool_test.go +++ b/core/vote/vote_pool_test.go @@ -68,6 +68,17 @@ type mockInvalidPOSA struct { consensus.PoSA } +// testBackend is a mock implementation of the live Ethereum message handler. +type testBackend struct { + eventMux *event.TypeMux +} + +func newTestBackend() *testBackend { + return &testBackend{eventMux: new(event.TypeMux)} +} +func (b *testBackend) IsMining() bool { return true } +func (b *testBackend) EventMux() *event.TypeMux { return b.eventMux } + func (p *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) { parentHeader := chain.GetHeaderByHash(header.ParentHash) if parentHeader == nil { @@ -167,7 +178,7 @@ func testVotePool(t *testing.T, isValidRules bool) { file.Close() os.Remove(journal) - voteManager, err := NewVoteManager(mux, params.TestChainConfig, chain, votePool, journal, walletPasswordDir, walletDir, mockEngine) + voteManager, err := NewVoteManager(newTestBackend(), params.TestChainConfig, chain, votePool, journal, walletPasswordDir, walletDir, mockEngine) if err != nil { t.Fatalf("failed to create vote managers") } diff --git a/eth/backend.go b/eth/backend.go index bdc93c9783..e4b0e0ae98 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -249,31 +249,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain) - // Create voteManager instance - if posa, ok := eth.engine.(consensus.PoSA); ok { - // Create votePool instance - votePool := vote.NewVotePool(chainConfig, eth.blockchain, posa) - eth.votePool = votePool - if parlia, ok := eth.engine.(*parlia.Parlia); ok { - parlia.VotePool = votePool - } else { - return nil, fmt.Errorf("Engine is not Parlia type") - } - log.Info("Create votePool successfully") - - if config.Miner.VoteEnable { - conf := stack.Config() - blsPasswordPath := stack.ResolvePath(conf.BLSPasswordFile) - blsWalletPath := stack.ResolvePath(conf.BLSWalletDir) - voteJournalPath := stack.ResolvePath(conf.VoteJournalDir) - if _, err := vote.NewVoteManager(eth.EventMux(), chainConfig, eth.blockchain, votePool, voteJournalPath, blsPasswordPath, blsWalletPath, posa); err != nil { - log.Error("Failed to Initialize voteManager", "err", err) - return nil, err - } - log.Info("Create voteManager successfully") - } - } - // Permit the downloader to use the trie cache allowance during fast sync cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit checkpoint := config.Checkpoint @@ -299,16 +274,39 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { }); err != nil { return nil, err } - if eth.votePool != nil { - eth.handler.votepool = eth.votePool + + eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) + eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) + + // Create voteManager instance + if posa, ok := eth.engine.(consensus.PoSA); ok { + // Create votePool instance + votePool := vote.NewVotePool(chainConfig, eth.blockchain, posa) + eth.votePool = votePool + if parlia, ok := eth.engine.(*parlia.Parlia); ok { + parlia.VotePool = votePool + } else { + return nil, fmt.Errorf("Engine is not Parlia type") + } + log.Info("Create votePool successfully") + eth.handler.votepool = votePool if stack.Config().EnableMaliciousVoteMonitor { eth.handler.maliciousVoteMonitor = monitor.NewMaliciousVoteMonitor() log.Info("Create MaliciousVoteMonitor successfully") } - } - eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) - eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) + if config.Miner.VoteEnable { + conf := stack.Config() + blsPasswordPath := stack.ResolvePath(conf.BLSPasswordFile) + blsWalletPath := stack.ResolvePath(conf.BLSWalletDir) + voteJournalPath := stack.ResolvePath(conf.VoteJournalDir) + if _, err := vote.NewVoteManager(eth, chainConfig, eth.blockchain, votePool, voteJournalPath, blsPasswordPath, blsWalletPath, posa); err != nil { + log.Error("Failed to Initialize voteManager", "err", err) + return nil, err + } + log.Info("Create voteManager successfully") + } + } gpoParams := config.GPO if gpoParams.Default == nil { diff --git a/miner/miner.go b/miner/miner.go index de575ee69c..3d355bca05 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -54,7 +54,7 @@ type Config struct { GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. Noverify bool // Disable remote mining solution verification(only useful in ethash). - VoteEnable bool // whether enable voting + VoteEnable bool // Whether to vote when mining } // Miner creates blocks and searches for proof-of-work values.