diff options
author | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-10-05 22:14:01 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-10-05 22:14:01 +0800 |
commit | 5b34fa538e54320778314081df97da561f7c6314 (patch) | |
tree | dca15c858b8ac4cd79ed7b7733260ab3021bbd0c /eth | |
parent | 8b865fa9bf75e728d5d76f5a1460e0c37d8b5f9e (diff) | |
parent | 7c7692933c21b77328a94eed714f66c276776197 (diff) | |
download | dexon-5b34fa538e54320778314081df97da561f7c6314.tar.gz dexon-5b34fa538e54320778314081df97da561f7c6314.tar.zst dexon-5b34fa538e54320778314081df97da561f7c6314.zip |
Merge pull request #1756 from obscuren/core-refactor
core, core/vm: refactor
Diffstat (limited to 'eth')
-rw-r--r-- | eth/backend.go | 22 | ||||
-rw-r--r-- | eth/filters/filter.go | 216 | ||||
-rw-r--r-- | eth/filters/filter_system.go | 133 | ||||
-rw-r--r-- | eth/gasprice.go | 4 | ||||
-rw-r--r-- | eth/handler.go | 66 | ||||
-rw-r--r-- | eth/handler_test.go | 158 | ||||
-rw-r--r-- | eth/helper_test.go | 20 | ||||
-rw-r--r-- | eth/protocol_test.go | 2 | ||||
-rw-r--r-- | eth/sync.go | 2 |
9 files changed, 486 insertions, 137 deletions
diff --git a/eth/backend.go b/eth/backend.go index 349dfa613..a480b4931 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -217,7 +217,7 @@ type Ethereum struct { // State manager for processing new blocks and managing the over all states blockProcessor *core.BlockProcessor txPool *core.TxPool - chainManager *core.ChainManager + blockchain *core.BlockChain accountManager *accounts.Manager whisper *whisper.Whisper pow *ethash.Ethash @@ -365,7 +365,7 @@ func New(config *Config) (*Ethereum, error) { eth.pow = ethash.New() } //genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) - eth.chainManager, err = core.NewChainManager(chainDb, eth.pow, eth.EventMux()) + eth.blockchain, err = core.NewBlockChain(chainDb, eth.pow, eth.EventMux()) if err != nil { if err == core.ErrNoGenesis { return nil, fmt.Errorf(`Genesis block not found. Please supply a genesis block with the "--genesis /path/to/file" argument`) @@ -373,11 +373,11 @@ func New(config *Config) (*Ethereum, error) { return nil, err } - eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit) + eth.txPool = core.NewTxPool(eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit) - eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.chainManager, eth.EventMux()) - eth.chainManager.SetProcessor(eth.blockProcessor) - eth.protocolManager = NewProtocolManager(config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.chainManager, chainDb) + eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.blockchain, eth.EventMux()) + eth.blockchain.SetProcessor(eth.blockProcessor) + eth.protocolManager = NewProtocolManager(config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb) eth.miner = miner.New(eth, eth.EventMux(), eth.pow) eth.miner.SetGasPrice(config.GasPrice) @@ -441,7 +441,7 @@ func (s *Ethereum) NodeInfo() *NodeInfo { DiscPort: int(node.UDP), TCPPort: int(node.TCP), ListenAddr: s.net.ListenAddr, - Td: s.ChainManager().Td().String(), + Td: s.BlockChain().Td().String(), } } @@ -478,7 +478,7 @@ func (s *Ethereum) PeersInfo() (peersinfo []*PeerInfo) { } func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { - s.chainManager.ResetWithGenesisBlock(gb) + s.blockchain.ResetWithGenesisBlock(gb) } func (s *Ethereum) StartMining(threads int) error { @@ -518,7 +518,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } // func (s *Ethereum) Logger() logger.LogSystem { return s.logger } func (s *Ethereum) Name() string { return s.net.Name } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } -func (s *Ethereum) ChainManager() *core.ChainManager { return s.chainManager } +func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcessor } func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper } @@ -581,7 +581,7 @@ func (self *Ethereum) AddPeer(nodeURL string) error { func (s *Ethereum) Stop() { s.net.Stop() - s.chainManager.Stop() + s.blockchain.Stop() s.protocolManager.Stop() s.txPool.Stop() s.eventMux.Stop() @@ -622,7 +622,7 @@ func (self *Ethereum) StartAutoDAG() { select { case <-timer: glog.V(logger.Info).Infof("checking DAG (ethash dir: %s)", ethash.DefaultDir) - currentBlock := self.ChainManager().CurrentBlock().NumberU64() + currentBlock := self.BlockChain().CurrentBlock().NumberU64() thisEpoch := currentBlock / epochLength if nextEpoch <= thisEpoch { if currentBlock%epochLength > autoDAGepochHeight { diff --git a/eth/filters/filter.go b/eth/filters/filter.go new file mode 100644 index 000000000..2bcf20d0c --- /dev/null +++ b/eth/filters/filter.go @@ -0,0 +1,216 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package filters + +import ( + "math" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/ethdb" +) + +type AccountChange struct { + Address, StateAddress []byte +} + +// Filtering interface +type Filter struct { + db ethdb.Database + earliest int64 + latest int64 + skip int + address []common.Address + max int + topics [][]common.Hash + + BlockCallback func(*types.Block, vm.Logs) + TransactionCallback func(*types.Transaction) + LogsCallback func(vm.Logs) +} + +// Create a new filter which uses a bloom filter on blocks to figure out whether a particular block +// is interesting or not. +func New(db ethdb.Database) *Filter { + return &Filter{db: db} +} + +// Set the earliest and latest block for filtering. +// -1 = latest block (i.e., the current block) +// hash = particular hash from-to +func (self *Filter) SetEarliestBlock(earliest int64) { + self.earliest = earliest +} + +func (self *Filter) SetLatestBlock(latest int64) { + self.latest = latest +} + +func (self *Filter) SetAddress(addr []common.Address) { + self.address = addr +} + +func (self *Filter) SetTopics(topics [][]common.Hash) { + self.topics = topics +} + +func (self *Filter) SetMax(max int) { + self.max = max +} + +func (self *Filter) SetSkip(skip int) { + self.skip = skip +} + +// Run filters logs with the current parameters set +func (self *Filter) Find() vm.Logs { + earliestBlock := core.GetBlock(self.db, core.GetHeadBlockHash(self.db)) + var earliestBlockNo uint64 = uint64(self.earliest) + if self.earliest == -1 { + earliestBlockNo = earliestBlock.NumberU64() + } + var latestBlockNo uint64 = uint64(self.latest) + if self.latest == -1 { + latestBlockNo = earliestBlock.NumberU64() + } + + var ( + logs vm.Logs + block *types.Block + ) + hash := core.GetCanonicalHash(self.db, latestBlockNo) + if hash != (common.Hash{}) { + block = core.GetBlock(self.db, hash) + } + +done: + for i := 0; block != nil; i++ { + // Quit on latest + switch { + case block.NumberU64() == 0: + break done + case block.NumberU64() < earliestBlockNo: + break done + case self.max <= len(logs): + break done + } + + // Use bloom filtering to see if this block is interesting given the + // current parameters + if self.bloomFilter(block) { + // Get the logs of the block + var ( + receipts = core.GetBlockReceipts(self.db, block.Hash()) + unfiltered vm.Logs + ) + for _, receipt := range receipts { + unfiltered = append(unfiltered, receipt.Logs()...) + } + logs = append(logs, self.FilterLogs(unfiltered)...) + } + + block = core.GetBlock(self.db, block.ParentHash()) + } + + skip := int(math.Min(float64(len(logs)), float64(self.skip))) + + return logs[skip:] +} + +func includes(addresses []common.Address, a common.Address) bool { + for _, addr := range addresses { + if addr == a { + return true + } + } + + return false +} + +func (self *Filter) FilterLogs(logs vm.Logs) vm.Logs { + var ret vm.Logs + + // Filter the logs for interesting stuff +Logs: + for _, log := range logs { + if len(self.address) > 0 && !includes(self.address, log.Address) { + continue + } + + logTopics := make([]common.Hash, len(self.topics)) + copy(logTopics, log.Topics) + + // If the to filtered topics is greater than the amount of topics in + // logs, skip. + if len(self.topics) > len(log.Topics) { + continue Logs + } + + for i, topics := range self.topics { + var match bool + for _, topic := range topics { + // common.Hash{} is a match all (wildcard) + if (topic == common.Hash{}) || log.Topics[i] == topic { + match = true + break + } + } + + if !match { + continue Logs + } + + } + + ret = append(ret, log) + } + + return ret +} + +func (self *Filter) bloomFilter(block *types.Block) bool { + if len(self.address) > 0 { + var included bool + for _, addr := range self.address { + if types.BloomLookup(block.Bloom(), addr) { + included = true + break + } + } + + if !included { + return false + } + } + + for _, sub := range self.topics { + var included bool + for _, topic := range sub { + if (topic == common.Hash{}) || types.BloomLookup(block.Bloom(), topic) { + included = true + break + } + } + if !included { + return false + } + } + + return true +} diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go new file mode 100644 index 000000000..4972dcd59 --- /dev/null +++ b/eth/filters/filter_system.go @@ -0,0 +1,133 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +// package filters implements an ethereum filtering system for block, +// transactions and log events. +package filters + +import ( + "sync" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/event" +) + +// FilterSystem manages filters that filter specific events such as +// block, transaction and log events. The Filtering system can be used to listen +// for specific LOG events fired by the EVM (Ethereum Virtual Machine). +type FilterSystem struct { + eventMux *event.TypeMux + + filterMu sync.RWMutex + filterId int + filters map[int]*Filter + + quit chan struct{} +} + +// NewFilterSystem returns a newly allocated filter manager +func NewFilterSystem(mux *event.TypeMux) *FilterSystem { + fs := &FilterSystem{ + eventMux: mux, + filters: make(map[int]*Filter), + } + go fs.filterLoop() + return fs +} + +// Stop quits the filter loop required for polling events +func (fs *FilterSystem) Stop() { + close(fs.quit) +} + +// Add adds a filter to the filter manager +func (fs *FilterSystem) Add(filter *Filter) (id int) { + fs.filterMu.Lock() + defer fs.filterMu.Unlock() + id = fs.filterId + fs.filters[id] = filter + fs.filterId++ + + return id +} + +// Remove removes a filter by filter id +func (fs *FilterSystem) Remove(id int) { + fs.filterMu.Lock() + defer fs.filterMu.Unlock() + if _, ok := fs.filters[id]; ok { + delete(fs.filters, id) + } +} + +// Get retrieves a filter installed using Add The filter may not be modified. +func (fs *FilterSystem) Get(id int) *Filter { + fs.filterMu.RLock() + defer fs.filterMu.RUnlock() + return fs.filters[id] +} + +// filterLoop waits for specific events from ethereum and fires their handlers +// when the filter matches the requirements. +func (fs *FilterSystem) filterLoop() { + // Subscribe to events + events := fs.eventMux.Subscribe( + //core.PendingBlockEvent{}, + core.ChainEvent{}, + core.TxPreEvent{}, + vm.Logs(nil)) + +out: + for { + select { + case <-fs.quit: + break out + case event := <-events.Chan(): + switch event := event.(type) { + case core.ChainEvent: + fs.filterMu.RLock() + for _, filter := range fs.filters { + if filter.BlockCallback != nil { + filter.BlockCallback(event.Block, event.Logs) + } + } + fs.filterMu.RUnlock() + + case core.TxPreEvent: + fs.filterMu.RLock() + for _, filter := range fs.filters { + if filter.TransactionCallback != nil { + filter.TransactionCallback(event.Tx) + } + } + fs.filterMu.RUnlock() + + case vm.Logs: + fs.filterMu.RLock() + for _, filter := range fs.filters { + if filter.LogsCallback != nil { + msgs := filter.FilterLogs(event) + if len(msgs) > 0 { + filter.LogsCallback(msgs) + } + } + } + fs.filterMu.RUnlock() + } + } + } +} diff --git a/eth/gasprice.go b/eth/gasprice.go index 3caad73c6..c08b96129 100644 --- a/eth/gasprice.go +++ b/eth/gasprice.go @@ -36,7 +36,7 @@ type blockPriceInfo struct { type GasPriceOracle struct { eth *Ethereum - chain *core.ChainManager + chain *core.BlockChain events event.Subscription blocks map[uint64]*blockPriceInfo firstProcessed, lastProcessed uint64 @@ -48,7 +48,7 @@ func NewGasPriceOracle(eth *Ethereum) (self *GasPriceOracle) { self = &GasPriceOracle{} self.blocks = make(map[uint64]*blockPriceInfo) self.eth = eth - self.chain = eth.chainManager + self.chain = eth.blockchain self.events = eth.EventMux().Subscribe( core.ChainEvent{}, core.ChainSplitEvent{}, diff --git a/eth/handler.go b/eth/handler.go index 52c9c4151..fc92338b4 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -60,9 +60,9 @@ func (ep extProt) GetHashes(hash common.Hash) error { return ep.getHashes(has func (ep extProt) GetBlock(hashes []common.Hash) error { return ep.getBlocks(hashes) } type ProtocolManager struct { - txpool txPool - chainman *core.ChainManager - chaindb ethdb.Database + txpool txPool + blockchain *core.BlockChain + chaindb ethdb.Database downloader *downloader.Downloader fetcher *fetcher.Fetcher @@ -87,17 +87,17 @@ type ProtocolManager struct { // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the ethereum network. -func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, chainman *core.ChainManager, chaindb ethdb.Database) *ProtocolManager { +func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) *ProtocolManager { // Create the protocol manager with the base fields manager := &ProtocolManager{ - eventMux: mux, - txpool: txpool, - chainman: chainman, - chaindb: chaindb, - peers: newPeerSet(), - newPeerCh: make(chan *peer, 1), - txsyncCh: make(chan *txsync), - quitSync: make(chan struct{}), + eventMux: mux, + txpool: txpool, + blockchain: blockchain, + chaindb: chaindb, + peers: newPeerSet(), + newPeerCh: make(chan *peer, 1), + txsyncCh: make(chan *txsync), + quitSync: make(chan struct{}), } // Initiate a sub-protocol for every implemented version we can handle manager.SubProtocols = make([]p2p.Protocol, len(ProtocolVersions)) @@ -116,15 +116,15 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po } } // Construct the different synchronisation mechanisms - manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.CurrentBlock, manager.chainman.GetTd, manager.chainman.InsertChain, manager.removePeer) + manager.downloader = downloader.New(manager.eventMux, manager.blockchain.HasBlock, manager.blockchain.GetBlock, manager.blockchain.CurrentBlock, manager.blockchain.GetTd, manager.blockchain.InsertChain, manager.removePeer) validator := func(block *types.Block, parent *types.Block) error { return core.ValidateHeader(pow, block.Header(), parent.Header(), true, false) } heighter := func() uint64 { - return manager.chainman.CurrentBlock().NumberU64() + return manager.blockchain.CurrentBlock().NumberU64() } - manager.fetcher = fetcher.New(manager.chainman.GetBlock, validator, manager.BroadcastBlock, heighter, manager.chainman.InsertChain, manager.removePeer) + manager.fetcher = fetcher.New(manager.blockchain.GetBlock, validator, manager.BroadcastBlock, heighter, manager.blockchain.InsertChain, manager.removePeer) return manager } @@ -187,7 +187,7 @@ func (pm *ProtocolManager) handle(p *peer) error { glog.V(logger.Debug).Infof("%v: peer connected [%s]", p, p.Name()) // Execute the Ethereum handshake - td, head, genesis := pm.chainman.Status() + td, head, genesis := pm.blockchain.Status() if err := p.Handshake(td, head, genesis); err != nil { glog.V(logger.Debug).Infof("%v: handshake failed: %v", p, err) return err @@ -252,7 +252,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { request.Amount = uint64(downloader.MaxHashFetch) } // Retrieve the hashes from the block chain and return them - hashes := pm.chainman.GetBlockHashesFromHash(request.Hash, request.Amount) + hashes := pm.blockchain.GetBlockHashesFromHash(request.Hash, request.Amount) if len(hashes) == 0 { glog.V(logger.Debug).Infof("invalid block hash %x", request.Hash.Bytes()[:4]) } @@ -268,9 +268,9 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { request.Amount = uint64(downloader.MaxHashFetch) } // Calculate the last block that should be retrieved, and short circuit if unavailable - last := pm.chainman.GetBlockByNumber(request.Number + request.Amount - 1) + last := pm.blockchain.GetBlockByNumber(request.Number + request.Amount - 1) if last == nil { - last = pm.chainman.CurrentBlock() + last = pm.blockchain.CurrentBlock() request.Amount = last.NumberU64() - request.Number + 1 } if last.NumberU64() < request.Number { @@ -278,7 +278,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } // Retrieve the hashes from the last block backwards, reverse and return hashes := []common.Hash{last.Hash()} - hashes = append(hashes, pm.chainman.GetBlockHashesFromHash(last.Hash(), request.Amount-1)...) + hashes = append(hashes, pm.blockchain.GetBlockHashesFromHash(last.Hash(), request.Amount-1)...) for i := 0; i < len(hashes)/2; i++ { hashes[i], hashes[len(hashes)-1-i] = hashes[len(hashes)-1-i], hashes[i] @@ -318,7 +318,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "msg %v: %v", msg, err) } // Retrieve the requested block, stopping if enough was found - if block := pm.chainman.GetBlock(hash); block != nil { + if block := pm.blockchain.GetBlock(hash); block != nil { blocks = append(blocks, block) bytes += block.Size() } @@ -358,9 +358,9 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { // Retrieve the next header satisfying the query var origin *types.Header if query.Origin.Hash != (common.Hash{}) { - origin = pm.chainman.GetHeader(query.Origin.Hash) + origin = pm.blockchain.GetHeader(query.Origin.Hash) } else { - origin = pm.chainman.GetHeaderByNumber(query.Origin.Number) + origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number) } if origin == nil { break @@ -373,7 +373,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { case query.Origin.Hash != (common.Hash{}) && query.Reverse: // Hash based traversal towards the genesis block for i := 0; i < int(query.Skip)+1; i++ { - if header := pm.chainman.GetHeader(query.Origin.Hash); header != nil { + if header := pm.blockchain.GetHeader(query.Origin.Hash); header != nil { query.Origin.Hash = header.ParentHash } else { unknown = true @@ -382,8 +382,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } case query.Origin.Hash != (common.Hash{}) && !query.Reverse: // Hash based traversal towards the leaf block - if header := pm.chainman.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil { - if pm.chainman.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash { + if header := pm.blockchain.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil { + if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash { query.Origin.Hash = header.Hash() } else { unknown = true @@ -466,7 +466,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "msg %v: %v", msg, err) } // Retrieve the requested block body, stopping if enough was found - if data := pm.chainman.GetBodyRLP(hash); len(data) != 0 { + if data := pm.blockchain.GetBodyRLP(hash); len(data) != 0 { bodies = append(bodies, data) bytes += len(data) } @@ -562,7 +562,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { // Schedule all the unknown hashes for retrieval unknown := make([]announce, 0, len(announces)) for _, block := range announces { - if !pm.chainman.HasBlock(block.Hash) { + if !pm.blockchain.HasBlock(block.Hash) { unknown = append(unknown, block) } } @@ -586,7 +586,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { request.Block.ReceivedAt = msg.ReceivedAt // Mark the block's arrival for whatever reason - _, chainHead, _ := pm.chainman.Status() + _, chainHead, _ := pm.blockchain.Status() jsonlogger.LogJson(&logger.EthChainReceivedNewBlock{ BlockHash: request.Block.Hash().Hex(), BlockNumber: request.Block.Number(), @@ -603,7 +603,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { // Update the peers total difficulty if needed, schedule a download if gapped if request.TD.Cmp(p.Td()) > 0 { p.SetTd(request.TD) - if request.TD.Cmp(new(big.Int).Add(pm.chainman.Td(), request.Block.Difficulty())) > 0 { + if request.TD.Cmp(new(big.Int).Add(pm.blockchain.Td(), request.Block.Difficulty())) > 0 { go pm.synchronise(p) } } @@ -645,8 +645,8 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) { if propagate { // Calculate the TD of the block (it's not imported yet, so block.Td is not valid) var td *big.Int - if parent := pm.chainman.GetBlock(block.ParentHash()); parent != nil { - td = new(big.Int).Add(block.Difficulty(), pm.chainman.GetTd(block.ParentHash())) + if parent := pm.blockchain.GetBlock(block.ParentHash()); parent != nil { + td = new(big.Int).Add(block.Difficulty(), pm.blockchain.GetTd(block.ParentHash())) } else { glog.V(logger.Error).Infof("propagating dangling block #%d [%x]", block.NumberU64(), hash[:4]) return @@ -659,7 +659,7 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) { glog.V(logger.Detail).Infof("propagated block %x to %d peers in %v", hash[:4], len(transfer), time.Since(block.ReceivedAt)) } // Otherwise if the block is indeed in out own chain, announce it - if pm.chainman.HasBlock(hash) { + if pm.blockchain.HasBlock(hash) { for _, peer := range peers { if peer.version < eth62 { peer.SendNewBlockHashes61([]common.Hash{hash}) diff --git a/eth/handler_test.go b/eth/handler_test.go index 6400d4e78..2b8c6168a 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -33,23 +33,23 @@ func testGetBlockHashes(t *testing.T, protocol int) { number int result int }{ - {common.Hash{}, 1, 0}, // Make sure non existent hashes don't return results - {pm.chainman.Genesis().Hash(), 1, 0}, // There are no hashes to retrieve up from the genesis - {pm.chainman.GetBlockByNumber(5).Hash(), 5, 5}, // All the hashes including the genesis requested - {pm.chainman.GetBlockByNumber(5).Hash(), 10, 5}, // More hashes than available till the genesis requested - {pm.chainman.GetBlockByNumber(100).Hash(), 10, 10}, // All hashes available from the middle of the chain - {pm.chainman.CurrentBlock().Hash(), 10, 10}, // All hashes available from the head of the chain - {pm.chainman.CurrentBlock().Hash(), limit, limit}, // Request the maximum allowed hash count - {pm.chainman.CurrentBlock().Hash(), limit + 1, limit}, // Request more than the maximum allowed hash count + {common.Hash{}, 1, 0}, // Make sure non existent hashes don't return results + {pm.blockchain.Genesis().Hash(), 1, 0}, // There are no hashes to retrieve up from the genesis + {pm.blockchain.GetBlockByNumber(5).Hash(), 5, 5}, // All the hashes including the genesis requested + {pm.blockchain.GetBlockByNumber(5).Hash(), 10, 5}, // More hashes than available till the genesis requested + {pm.blockchain.GetBlockByNumber(100).Hash(), 10, 10}, // All hashes available from the middle of the chain + {pm.blockchain.CurrentBlock().Hash(), 10, 10}, // All hashes available from the head of the chain + {pm.blockchain.CurrentBlock().Hash(), limit, limit}, // Request the maximum allowed hash count + {pm.blockchain.CurrentBlock().Hash(), limit + 1, limit}, // Request more than the maximum allowed hash count } // Run each of the tests and verify the results against the chain for i, tt := range tests { // Assemble the hash response we would like to receive resp := make([]common.Hash, tt.result) if len(resp) > 0 { - from := pm.chainman.GetBlock(tt.origin).NumberU64() - 1 + from := pm.blockchain.GetBlock(tt.origin).NumberU64() - 1 for j := 0; j < len(resp); j++ { - resp[j] = pm.chainman.GetBlockByNumber(uint64(int(from) - j)).Hash() + resp[j] = pm.blockchain.GetBlockByNumber(uint64(int(from) - j)).Hash() } } // Send the hash request and verify the response @@ -76,11 +76,11 @@ func testGetBlockHashesFromNumber(t *testing.T, protocol int) { number int result int }{ - {pm.chainman.CurrentBlock().NumberU64() + 1, 1, 0}, // Out of bounds requests should return empty - {pm.chainman.CurrentBlock().NumberU64(), 1, 1}, // Make sure the head hash can be retrieved - {pm.chainman.CurrentBlock().NumberU64() - 4, 5, 5}, // All hashes, including the head hash requested - {pm.chainman.CurrentBlock().NumberU64() - 4, 10, 5}, // More hashes requested than available till the head - {pm.chainman.CurrentBlock().NumberU64() - 100, 10, 10}, // All hashes available from the middle of the chain + {pm.blockchain.CurrentBlock().NumberU64() + 1, 1, 0}, // Out of bounds requests should return empty + {pm.blockchain.CurrentBlock().NumberU64(), 1, 1}, // Make sure the head hash can be retrieved + {pm.blockchain.CurrentBlock().NumberU64() - 4, 5, 5}, // All hashes, including the head hash requested + {pm.blockchain.CurrentBlock().NumberU64() - 4, 10, 5}, // More hashes requested than available till the head + {pm.blockchain.CurrentBlock().NumberU64() - 100, 10, 10}, // All hashes available from the middle of the chain {0, 10, 10}, // All hashes available from the root of the chain {0, limit, limit}, // Request the maximum allowed hash count {0, limit + 1, limit}, // Request more than the maximum allowed hash count @@ -91,7 +91,7 @@ func testGetBlockHashesFromNumber(t *testing.T, protocol int) { // Assemble the hash response we would like to receive resp := make([]common.Hash, tt.result) for j := 0; j < len(resp); j++ { - resp[j] = pm.chainman.GetBlockByNumber(tt.origin + uint64(j)).Hash() + resp[j] = pm.blockchain.GetBlockByNumber(tt.origin + uint64(j)).Hash() } // Send the hash request and verify the response p2p.Send(peer.app, 0x08, getBlockHashesFromNumberData{tt.origin, uint64(tt.number)}) @@ -117,22 +117,22 @@ func testGetBlocks(t *testing.T, protocol int) { available []bool // Availability of explicitly requested blocks expected int // Total number of existing blocks to expect }{ - {1, nil, nil, 1}, // A single random block should be retrievable - {10, nil, nil, 10}, // Multiple random blocks should be retrievable - {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable - {limit + 1, nil, nil, limit}, // No more that the possible block count should be returned - {0, []common.Hash{pm.chainman.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable - {0, []common.Hash{pm.chainman.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable - {0, []common.Hash{common.Hash{}}, []bool{false}, 0}, // A non existent block should not be returned + {1, nil, nil, 1}, // A single random block should be retrievable + {10, nil, nil, 10}, // Multiple random blocks should be retrievable + {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable + {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned + {0, []common.Hash{pm.blockchain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable + {0, []common.Hash{pm.blockchain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable + {0, []common.Hash{common.Hash{}}, []bool{false}, 0}, // A non existent block should not be returned // Existing and non-existing blocks interleaved should not cause problems {0, []common.Hash{ common.Hash{}, - pm.chainman.GetBlockByNumber(1).Hash(), + pm.blockchain.GetBlockByNumber(1).Hash(), common.Hash{}, - pm.chainman.GetBlockByNumber(10).Hash(), + pm.blockchain.GetBlockByNumber(10).Hash(), common.Hash{}, - pm.chainman.GetBlockByNumber(100).Hash(), + pm.blockchain.GetBlockByNumber(100).Hash(), common.Hash{}, }, []bool{false, true, false, true, false, true, false}, 3}, } @@ -144,11 +144,11 @@ func testGetBlocks(t *testing.T, protocol int) { for j := 0; j < tt.random; j++ { for { - num := rand.Int63n(int64(pm.chainman.CurrentBlock().NumberU64())) + num := rand.Int63n(int64(pm.blockchain.CurrentBlock().NumberU64())) if !seen[num] { seen[num] = true - block := pm.chainman.GetBlockByNumber(uint64(num)) + block := pm.blockchain.GetBlockByNumber(uint64(num)) hashes = append(hashes, block.Hash()) if len(blocks) < tt.expected { blocks = append(blocks, block) @@ -160,7 +160,7 @@ func testGetBlocks(t *testing.T, protocol int) { for j, hash := range tt.explicit { hashes = append(hashes, hash) if tt.available[j] && len(blocks) < tt.expected { - blocks = append(blocks, pm.chainman.GetBlock(hash)) + blocks = append(blocks, pm.blockchain.GetBlock(hash)) } } // Send the hash request and verify the response @@ -194,83 +194,83 @@ func testGetBlockHeaders(t *testing.T, protocol int) { }{ // A single random block should be retrievable by hash and number too { - &getBlockHeadersData{Origin: hashOrNumber{Hash: pm.chainman.GetBlockByNumber(limit / 2).Hash()}, Amount: 1}, - []common.Hash{pm.chainman.GetBlockByNumber(limit / 2).Hash()}, + &getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, Amount: 1}, + []common.Hash{pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1}, - []common.Hash{pm.chainman.GetBlockByNumber(limit / 2).Hash()}, + []common.Hash{pm.blockchain.GetBlockByNumber(limit / 2).Hash()}, }, // Multiple headers should be retrievable in both directions { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3}, []common.Hash{ - pm.chainman.GetBlockByNumber(limit / 2).Hash(), - pm.chainman.GetBlockByNumber(limit/2 + 1).Hash(), - pm.chainman.GetBlockByNumber(limit/2 + 2).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 1).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 2).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true}, []common.Hash{ - pm.chainman.GetBlockByNumber(limit / 2).Hash(), - pm.chainman.GetBlockByNumber(limit/2 - 1).Hash(), - pm.chainman.GetBlockByNumber(limit/2 - 2).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 1).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 2).Hash(), }, }, // Multiple headers with skip lists should be retrievable { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3}, []common.Hash{ - pm.chainman.GetBlockByNumber(limit / 2).Hash(), - pm.chainman.GetBlockByNumber(limit/2 + 4).Hash(), - pm.chainman.GetBlockByNumber(limit/2 + 8).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 4).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 + 8).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true}, []common.Hash{ - pm.chainman.GetBlockByNumber(limit / 2).Hash(), - pm.chainman.GetBlockByNumber(limit/2 - 4).Hash(), - pm.chainman.GetBlockByNumber(limit/2 - 8).Hash(), + pm.blockchain.GetBlockByNumber(limit / 2).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 4).Hash(), + pm.blockchain.GetBlockByNumber(limit/2 - 8).Hash(), }, }, // The chain endpoints should be retrievable { &getBlockHeadersData{Origin: hashOrNumber{Number: 0}, Amount: 1}, - []common.Hash{pm.chainman.GetBlockByNumber(0).Hash()}, + []common.Hash{pm.blockchain.GetBlockByNumber(0).Hash()}, }, { - &getBlockHeadersData{Origin: hashOrNumber{Number: pm.chainman.CurrentBlock().NumberU64()}, Amount: 1}, - []common.Hash{pm.chainman.CurrentBlock().Hash()}, + &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64()}, Amount: 1}, + []common.Hash{pm.blockchain.CurrentBlock().Hash()}, }, // Ensure protocol limits are honored { - &getBlockHeadersData{Origin: hashOrNumber{Number: pm.chainman.CurrentBlock().NumberU64() - 1}, Amount: limit + 10, Reverse: true}, - pm.chainman.GetBlockHashesFromHash(pm.chainman.CurrentBlock().Hash(), limit), + &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 1}, Amount: limit + 10, Reverse: true}, + pm.blockchain.GetBlockHashesFromHash(pm.blockchain.CurrentBlock().Hash(), limit), }, // Check that requesting more than available is handled gracefully { - &getBlockHeadersData{Origin: hashOrNumber{Number: pm.chainman.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3}, + &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3}, []common.Hash{ - pm.chainman.GetBlockByNumber(pm.chainman.CurrentBlock().NumberU64() - 4).Hash(), - pm.chainman.GetBlockByNumber(pm.chainman.CurrentBlock().NumberU64()).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 3, Amount: 3, Reverse: true}, []common.Hash{ - pm.chainman.GetBlockByNumber(4).Hash(), - pm.chainman.GetBlockByNumber(0).Hash(), + pm.blockchain.GetBlockByNumber(4).Hash(), + pm.blockchain.GetBlockByNumber(0).Hash(), }, }, // Check that requesting more than available is handled gracefully, even if mid skip { - &getBlockHeadersData{Origin: hashOrNumber{Number: pm.chainman.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3}, + &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3}, []common.Hash{ - pm.chainman.GetBlockByNumber(pm.chainman.CurrentBlock().NumberU64() - 4).Hash(), - pm.chainman.GetBlockByNumber(pm.chainman.CurrentBlock().NumberU64() - 1).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(), + pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 1).Hash(), }, }, { &getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true}, []common.Hash{ - pm.chainman.GetBlockByNumber(4).Hash(), - pm.chainman.GetBlockByNumber(1).Hash(), + pm.blockchain.GetBlockByNumber(4).Hash(), + pm.blockchain.GetBlockByNumber(1).Hash(), }, }, // Check that non existing headers aren't returned @@ -278,7 +278,7 @@ func testGetBlockHeaders(t *testing.T, protocol int) { &getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1}, []common.Hash{}, }, { - &getBlockHeadersData{Origin: hashOrNumber{Number: pm.chainman.CurrentBlock().NumberU64() + 1}, Amount: 1}, + &getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() + 1}, Amount: 1}, []common.Hash{}, }, } @@ -287,7 +287,7 @@ func testGetBlockHeaders(t *testing.T, protocol int) { // Collect the headers to expect in the response headers := []*types.Header{} for _, hash := range tt.expect { - headers = append(headers, pm.chainman.GetBlock(hash).Header()) + headers = append(headers, pm.blockchain.GetBlock(hash).Header()) } // Send the hash request and verify the response p2p.Send(peer.app, 0x03, tt.query) @@ -315,22 +315,22 @@ func testGetBlockBodies(t *testing.T, protocol int) { available []bool // Availability of explicitly requested blocks expected int // Total number of existing blocks to expect }{ - {1, nil, nil, 1}, // A single random block should be retrievable - {10, nil, nil, 10}, // Multiple random blocks should be retrievable - {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable - {limit + 1, nil, nil, limit}, // No more that the possible block count should be returned - {0, []common.Hash{pm.chainman.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable - {0, []common.Hash{pm.chainman.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable - {0, []common.Hash{common.Hash{}}, []bool{false}, 0}, // A non existent block should not be returned + {1, nil, nil, 1}, // A single random block should be retrievable + {10, nil, nil, 10}, // Multiple random blocks should be retrievable + {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable + {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned + {0, []common.Hash{pm.blockchain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable + {0, []common.Hash{pm.blockchain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable + {0, []common.Hash{common.Hash{}}, []bool{false}, 0}, // A non existent block should not be returned // Existing and non-existing blocks interleaved should not cause problems {0, []common.Hash{ common.Hash{}, - pm.chainman.GetBlockByNumber(1).Hash(), + pm.blockchain.GetBlockByNumber(1).Hash(), common.Hash{}, - pm.chainman.GetBlockByNumber(10).Hash(), + pm.blockchain.GetBlockByNumber(10).Hash(), common.Hash{}, - pm.chainman.GetBlockByNumber(100).Hash(), + pm.blockchain.GetBlockByNumber(100).Hash(), common.Hash{}, }, []bool{false, true, false, true, false, true, false}, 3}, } @@ -342,11 +342,11 @@ func testGetBlockBodies(t *testing.T, protocol int) { for j := 0; j < tt.random; j++ { for { - num := rand.Int63n(int64(pm.chainman.CurrentBlock().NumberU64())) + num := rand.Int63n(int64(pm.blockchain.CurrentBlock().NumberU64())) if !seen[num] { seen[num] = true - block := pm.chainman.GetBlockByNumber(uint64(num)) + block := pm.blockchain.GetBlockByNumber(uint64(num)) hashes = append(hashes, block.Hash()) if len(bodies) < tt.expected { bodies = append(bodies, &blockBody{Transactions: block.Transactions(), Uncles: block.Uncles()}) @@ -358,7 +358,7 @@ func testGetBlockBodies(t *testing.T, protocol int) { for j, hash := range tt.explicit { hashes = append(hashes, hash) if tt.available[j] && len(bodies) < tt.expected { - block := pm.chainman.GetBlock(hash) + block := pm.blockchain.GetBlock(hash) bodies = append(bodies, &blockBody{Transactions: block.Transactions(), Uncles: block.Uncles()}) } } @@ -442,11 +442,11 @@ func testGetNodeData(t *testing.T, protocol int) { statedb.Put(hashes[i].Bytes(), data[i]) } accounts := []common.Address{testBankAddress, acc1Addr, acc2Addr} - for i := uint64(0); i <= pm.chainman.CurrentBlock().NumberU64(); i++ { - trie := state.New(pm.chainman.GetBlockByNumber(i).Root(), statedb) + for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ { + trie := state.New(pm.blockchain.GetBlockByNumber(i).Root(), statedb) for j, acc := range accounts { - bw := pm.chainman.State().GetBalance(acc) + bw := pm.blockchain.State().GetBalance(acc) bh := trie.GetBalance(acc) if (bw != nil && bh == nil) || (bw == nil && bh != nil) { @@ -505,8 +505,8 @@ func testGetReceipt(t *testing.T, protocol int) { // Collect the hashes to request, and the response to expect hashes := []common.Hash{} - for i := uint64(0); i <= pm.chainman.CurrentBlock().NumberU64(); i++ { - for _, tx := range pm.chainman.GetBlockByNumber(i).Transactions() { + for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ { + for _, tx := range pm.blockchain.GetBlockByNumber(i).Transactions() { hashes = append(hashes, tx.Hash()) } } diff --git a/eth/helper_test.go b/eth/helper_test.go index 034751f7f..e42fa1f82 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -30,18 +30,18 @@ var ( // channels for different events. func newTestProtocolManager(blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) *ProtocolManager { var ( - evmux = new(event.TypeMux) - pow = new(core.FakePow) - db, _ = ethdb.NewMemDatabase() - genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{testBankAddress, testBankFunds}) - chainman, _ = core.NewChainManager(db, pow, evmux) - blockproc = core.NewBlockProcessor(db, pow, chainman, evmux) + evmux = new(event.TypeMux) + pow = new(core.FakePow) + db, _ = ethdb.NewMemDatabase() + genesis = core.WriteGenesisBlockForTesting(db, core.GenesisAccount{testBankAddress, testBankFunds}) + blockchain, _ = core.NewBlockChain(db, pow, evmux) + blockproc = core.NewBlockProcessor(db, pow, blockchain, evmux) ) - chainman.SetProcessor(blockproc) - if _, err := chainman.InsertChain(core.GenerateChain(genesis, db, blocks, generator)); err != nil { + blockchain.SetProcessor(blockproc) + if _, err := blockchain.InsertChain(core.GenerateChain(genesis, db, blocks, generator)); err != nil { panic(err) } - pm := NewProtocolManager(NetworkId, evmux, &testTxPool{added: newtx}, pow, chainman, db) + pm := NewProtocolManager(NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db) pm.Start() return pm } @@ -116,7 +116,7 @@ func newTestPeer(name string, version int, pm *ProtocolManager, shake bool) (*te } // Execute any implicitly requested handshakes and return if shake { - td, head, genesis := pm.chainman.Status() + td, head, genesis := pm.blockchain.Status() tp.handshake(nil, td, head, genesis) } return tp, errc diff --git a/eth/protocol_test.go b/eth/protocol_test.go index bc3b5acfc..523e6c1eb 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -45,7 +45,7 @@ func TestStatusMsgErrors64(t *testing.T) { testStatusMsgErrors(t, 64) } func testStatusMsgErrors(t *testing.T, protocol int) { pm := newTestProtocolManager(0, nil, nil) - td, currentBlock, genesis := pm.chainman.Status() + td, currentBlock, genesis := pm.blockchain.Status() defer pm.Stop() tests := []struct { diff --git a/eth/sync.go b/eth/sync.go index b4dea4b0f..5a2031c68 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -160,7 +160,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) { return } // Make sure the peer's TD is higher than our own. If not drop. - if peer.Td().Cmp(pm.chainman.Td()) <= 0 { + if peer.Td().Cmp(pm.blockchain.Td()) <= 0 { return } // Otherwise try to sync with the downloader |