diff --git a/cmd/tomo/main.go b/cmd/tomo/main.go index 26ebe5ace4..f5c397310c 100644 --- a/cmd/tomo/main.go +++ b/cmd/tomo/main.go @@ -290,6 +290,14 @@ 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 { + utils.Fatalf("Only validator can mine blocks") + } + // Use a reduced number of threads if requested if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 { type threaded interface { diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 2aa4648552..1157ab00a3 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -367,6 +367,18 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *type return c.verifySeal(chain, header, parents) } +func (c *Clique) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*Snapshot, error) { + number := header.Number.Uint64() + if number == 0 { + return nil, nil + } + snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + return nil, err + } + return snap, nil +} + // snapshot retrieves the authorization snapshot at a given point in time. func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints diff --git a/eth/backend.go b/eth/backend.go index 94aad23101..11e95c1d74 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -334,6 +334,26 @@ func (self *Ethereum) SetEtherbase(etherbase common.Address) { self.miner.SetEtherbase(etherbase) } +func (s *Ethereum) ValidateMiner() (bool, error) { + eb, err := s.Etherbase() + if err != nil { + return false, err + } + if c, ok := s.engine.(*clique.Clique); !ok { + return false, fmt.Errorf("Only verify miners in Clique protocol") + } else { + //check if miner's wallet is in set of validators + snap, err := c.GetSnapshot(s.blockchain, s.blockchain.CurrentHeader()) + if err != nil { + return false, fmt.Errorf("Can't verify miner: %v", err) + } + if _, authorized := snap.Signers[eb]; !authorized { + return false, fmt.Errorf("This miner doesn't belong to set of validators") + } + } + return true, nil +} + func (s *Ethereum) StartMining(local bool) error { eb, err := s.Etherbase() if err != nil {