From d6254f827bf493c1471a806b7b8a0e9b86c8c420 Mon Sep 17 00:00:00 2001 From: gary rong Date: Thu, 20 Sep 2018 20:09:30 +0800 Subject: all: protect self-mined block during reorg (#17656) --- eth/backend.go | 28 ++++++++++++++++++++++++++-- eth/handler_test.go | 2 +- eth/helper_test.go | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) (limited to 'eth') diff --git a/eth/backend.go b/eth/backend.go index 7d8060d77..90d185ed4 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -156,7 +156,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } cacheConfig = &core.CacheConfig{Disabled: config.NoPruning, TrieNodeLimit: config.TrieCache, TrieTimeLimit: config.TrieTimeout} ) - eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig) + eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig, eth.isMinerAccount) if err != nil { return nil, err } @@ -334,6 +334,30 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) { return common.Address{}, fmt.Errorf("etherbase must be explicitly specified") } +// isMinerAccount checks whether the specified address is a miner account. +// +// This function is used during block chain reorg checking to determine +// whether a block is mined by local accounts. We regard two types of +// accounts as local account: etherbase and accounts specified via +// `txpool.locals` flag. +func (s *Ethereum) isMinerAccount(addr common.Address) bool { + // Check whether the given address is etherbase. + s.lock.RLock() + etherbase := s.etherbase + s.lock.RUnlock() + if addr == etherbase { + return true + } + // Check whether the given address is specified by `txpool.local` + // CLI flag. + for _, account := range s.config.TxPool.Locals { + if account == addr { + return true + } + } + return false +} + // SetEtherbase sets the mining reward address. func (s *Ethereum) SetEtherbase(etherbase common.Address) { s.lock.Lock() @@ -366,7 +390,7 @@ func (s *Ethereum) StartMining(threads int) error { s.lock.RUnlock() s.txPool.SetGasPrice(price) - // Configure the local mining addess + // Configure the local mining address eb, err := s.Etherbase() if err != nil { log.Error("Cannot start mining without etherbase", "err", err) diff --git a/eth/handler_test.go b/eth/handler_test.go index dfaee2a15..0885a0448 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -472,7 +472,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked} gspec = &core.Genesis{Config: config} genesis = gspec.MustCommit(db) - blockchain, _ = core.NewBlockChain(db, nil, config, pow, vm.Config{}) + blockchain, _ = core.NewBlockChain(db, nil, config, pow, vm.Config{}, nil) ) pm, err := NewProtocolManager(config, downloader.FullSync, DefaultConfig.NetworkId, evmux, new(testTxPool), pow, blockchain, db) if err != nil { diff --git a/eth/helper_test.go b/eth/helper_test.go index 3d2ab0aba..3c101f658 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -59,7 +59,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}}, } genesis = gspec.MustCommit(db) - blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}) + blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil) ) chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, generator) if _, err := blockchain.InsertChain(chain); err != nil { -- cgit