diff --git a/cmd/tomo/main.go b/cmd/tomo/main.go index 4daa19bb06..52e4f1bb69 100644 --- a/cmd/tomo/main.go +++ b/cmd/tomo/main.go @@ -290,28 +290,67 @@ func startNode(ctx *cli.Context, stack *node.Node) { if err := stack.Service(ðereum); err != nil { utils.Fatalf("Ethereum service not running: %v", err) } - - // Mining only enabled for validator nodes - if ok, err := ethereum.ValidateMiner(); err != nil { - utils.Fatalf("Can't verify validator permission: %v", err) - } else if !ok { - log.Info("Only validator can mine blocks. Cancel mining on this node") - return - } - - // Use a reduced number of threads if requested - if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 { - type threaded interface { - SetThreads(threads int) + go func() { + started := false + ok, err := ethereum.ValidateMiner() + if err != nil { + utils.Fatalf("Can't verify validator permission: %v", err) } - if th, ok := ethereum.Engine().(threaded); ok { - th.SetThreads(threads) + if ok { + log.Info("Validator found. Enabling mining mode...") + // Use a reduced number of threads if requested + if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 { + type threaded interface { + SetThreads(threads int) + } + if th, ok := ethereum.Engine().(threaded); ok { + th.SetThreads(threads) + } + } + // Set the gas price to the limits from the CLI and start mining + ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) + if err := ethereum.StartMining(true); err != nil { + utils.Fatalf("Failed to start mining: %v", err) + } + started = true + log.Info("Enabled mining node!!!") } - } - // Set the gas price to the limits from the CLI and start mining - ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) - if err := ethereum.StartMining(true); err != nil { - utils.Fatalf("Failed to start mining: %v", err) - } + + for { + if ethereum.Checkpoint() { + //Checkpoint!!! It's time to reconcile node's state... + ok, err := ethereum.ValidateMiner() + if err != nil { + utils.Fatalf("Can't verify validator permission: %v", err) + } + if !ok { + log.Info("Only validator can mine blocks. Cancelling mining on this node...") + if started { + ethereum.StopMining() + started = false + } + log.Info("Cancelled mining mode!!!") + } else if !started { + log.Info("Validator found. Enabling mining mode...") + // Use a reduced number of threads if requested + if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 { + type threaded interface { + SetThreads(threads int) + } + if th, ok := ethereum.Engine().(threaded); ok { + th.SetThreads(threads) + } + } + // Set the gas price to the limits from the CLI and start mining + ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) + if err := ethereum.StartMining(true); err != nil { + utils.Fatalf("Failed to start mining: %v", err) + } + started = true + log.Info("Enabled mining node!!!") + } + } + } + }() } } diff --git a/eth/backend.go b/eth/backend.go index 1908a38a22..bd6a53c3be 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -334,6 +334,7 @@ func (self *Ethereum) SetEtherbase(etherbase common.Address) { self.miner.SetEtherbase(etherbase) } +// ValidateMiner checks if node's address is in set of validators func (s *Ethereum) ValidateMiner() (bool, error) { eb, err := s.Etherbase() if err != nil { @@ -356,6 +357,11 @@ func (s *Ethereum) ValidateMiner() (bool, error) { return true, nil } +func (s *Ethereum) Checkpoint() bool { + number := s.blockchain.CurrentHeader().Number.Uint64() + return number%s.chainConfig.Clique.Epoch == 1 || number == 0 +} + func (s *Ethereum) StartMining(local bool) error { eb, err := s.Etherbase() if err != nil {