diff options
Diffstat (limited to 'eth/backend.go')
-rw-r--r-- | eth/backend.go | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/eth/backend.go b/eth/backend.go index 90d185ed4..ca0b13eed 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.isMinerAccount) + eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig, eth.shouldPreserve) if err != nil { return nil, err } @@ -334,30 +334,60 @@ 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. +// isLocalBlock checks whether the specified block is mined +// by local miner accounts. // -// 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 { +// We regard two types of accounts as local miner account: etherbase +// and accounts specified via `txpool.locals` flag. +func (s *Ethereum) isLocalBlock(block *types.Block) bool { + author, err := s.engine.Author(block.Header()) + if err != nil { + log.Warn("Failed to retrieve block author", "number", block.NumberU64(), "hash", block.Hash(), "err", err) + return false + } // Check whether the given address is etherbase. s.lock.RLock() etherbase := s.etherbase s.lock.RUnlock() - if addr == etherbase { + if author == 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 { + if account == author { return true } } return false } +// shouldPreserve checks whether we should preserve the given block +// during the chain reorg depending on whether the author of block +// is a local account. +func (s *Ethereum) shouldPreserve(block *types.Block) bool { + // The reason we need to disable the self-reorg preserving for clique + // is it can be probable to introduce a deadlock. + // + // e.g. If there are 7 available signers + // + // r1 A + // r2 B + // r3 C + // r4 D + // r5 A [X] F G + // r6 [X] + // + // In the round5, the inturn signer E is offline, so the worst case + // is A, F and G sign the block of round5 and reject the block of opponents + // and in the round6, the last available signer B is offline, the whole + // network is stuck. + if _, ok := s.engine.(*clique.Clique); ok { + return false + } + return s.isLocalBlock(block) +} + // SetEtherbase sets the mining reward address. func (s *Ethereum) SetEtherbase(etherbase common.Address) { s.lock.Lock() |