Merge pull request #1756 from obscuren/core-refactor
core, core/vm: refactor
This commit is contained in:
@ -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 {
|
||||
|
216
eth/filters/filter.go
Normal file
216
eth/filters/filter.go
Normal file
@ -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
|
||||
}
|
133
eth/filters/filter_system.go
Normal file
133
eth/filters/filter_system.go
Normal file
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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{},
|
||||
|
@ -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})
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user