core, consensus: pluggable consensus engines (#3817)
This commit adds pluggable consensus engines to go-ethereum. In short, it introduces a generic consensus interface, and refactors the entire codebase to use this interface.
This commit is contained in:
committed by
Felix Lange
parent
e50a5b7771
commit
09777952ee
93
eth/api.go
93
eth/api.go
@ -26,7 +26,6 @@ import (
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -37,6 +36,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/miner"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
@ -56,18 +56,18 @@ func NewPublicEthereumAPI(e *Ethereum) *PublicEthereumAPI {
|
||||
}
|
||||
|
||||
// Etherbase is the address that mining rewards will be send to
|
||||
func (s *PublicEthereumAPI) Etherbase() (common.Address, error) {
|
||||
return s.e.Etherbase()
|
||||
func (api *PublicEthereumAPI) Etherbase() (common.Address, error) {
|
||||
return api.e.Etherbase()
|
||||
}
|
||||
|
||||
// Coinbase is the address that mining rewards will be send to (alias for Etherbase)
|
||||
func (s *PublicEthereumAPI) Coinbase() (common.Address, error) {
|
||||
return s.Etherbase()
|
||||
func (api *PublicEthereumAPI) Coinbase() (common.Address, error) {
|
||||
return api.Etherbase()
|
||||
}
|
||||
|
||||
// Hashrate returns the POW hashrate
|
||||
func (s *PublicEthereumAPI) Hashrate() hexutil.Uint64 {
|
||||
return hexutil.Uint64(s.e.Miner().HashRate())
|
||||
func (api *PublicEthereumAPI) Hashrate() hexutil.Uint64 {
|
||||
return hexutil.Uint64(api.e.Miner().HashRate())
|
||||
}
|
||||
|
||||
// PublicMinerAPI provides an API to control the miner.
|
||||
@ -79,34 +79,34 @@ type PublicMinerAPI struct {
|
||||
|
||||
// NewPublicMinerAPI create a new PublicMinerAPI instance.
|
||||
func NewPublicMinerAPI(e *Ethereum) *PublicMinerAPI {
|
||||
agent := miner.NewRemoteAgent(e.Pow())
|
||||
agent := miner.NewRemoteAgent(e.BlockChain(), e.Engine())
|
||||
e.Miner().Register(agent)
|
||||
|
||||
return &PublicMinerAPI{e, agent}
|
||||
}
|
||||
|
||||
// Mining returns an indication if this node is currently mining.
|
||||
func (s *PublicMinerAPI) Mining() bool {
|
||||
return s.e.IsMining()
|
||||
func (api *PublicMinerAPI) Mining() bool {
|
||||
return api.e.IsMining()
|
||||
}
|
||||
|
||||
// SubmitWork can be used by external miner to submit their POW solution. It returns an indication if the work was
|
||||
// accepted. Note, this is not an indication if the provided work was valid!
|
||||
func (s *PublicMinerAPI) SubmitWork(nonce types.BlockNonce, solution, digest common.Hash) bool {
|
||||
return s.agent.SubmitWork(nonce, digest, solution)
|
||||
func (api *PublicMinerAPI) SubmitWork(nonce types.BlockNonce, solution, digest common.Hash) bool {
|
||||
return api.agent.SubmitWork(nonce, digest, solution)
|
||||
}
|
||||
|
||||
// GetWork returns a work package for external miner. The work package consists of 3 strings
|
||||
// result[0], 32 bytes hex encoded current block header pow-hash
|
||||
// result[1], 32 bytes hex encoded seed hash used for DAG
|
||||
// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
|
||||
func (s *PublicMinerAPI) GetWork() ([3]string, error) {
|
||||
if !s.e.IsMining() {
|
||||
if err := s.e.StartMining(0); err != nil {
|
||||
func (api *PublicMinerAPI) GetWork() ([3]string, error) {
|
||||
if !api.e.IsMining() {
|
||||
if err := api.e.StartMining(); err != nil {
|
||||
return [3]string{}, err
|
||||
}
|
||||
}
|
||||
work, err := s.agent.GetWork()
|
||||
work, err := api.agent.GetWork()
|
||||
if err != nil {
|
||||
return work, fmt.Errorf("mining not ready: %v", err)
|
||||
}
|
||||
@ -116,8 +116,8 @@ func (s *PublicMinerAPI) GetWork() ([3]string, error) {
|
||||
// SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined
|
||||
// hash rate of all miners which submit work through this node. It accepts the miner hash rate and an identifier which
|
||||
// must be unique between nodes.
|
||||
func (s *PublicMinerAPI) SubmitHashrate(hashrate hexutil.Uint64, id common.Hash) bool {
|
||||
s.agent.SubmitHashrate(id, uint64(hashrate))
|
||||
func (api *PublicMinerAPI) SubmitHashrate(hashrate hexutil.Uint64, id common.Hash) bool {
|
||||
api.agent.SubmitHashrate(id, uint64(hashrate))
|
||||
return true
|
||||
}
|
||||
|
||||
@ -132,47 +132,59 @@ func NewPrivateMinerAPI(e *Ethereum) *PrivateMinerAPI {
|
||||
return &PrivateMinerAPI{e: e}
|
||||
}
|
||||
|
||||
// Start the miner with the given number of threads. If threads is nil the number of
|
||||
// workers started is equal to the number of logical CPU's that are usable by this process.
|
||||
func (s *PrivateMinerAPI) Start(threads *int) (bool, error) {
|
||||
var err error
|
||||
if threads == nil {
|
||||
err = s.e.StartMining(runtime.NumCPU())
|
||||
} else {
|
||||
err = s.e.StartMining(*threads)
|
||||
// Start the miner with the given number of threads. If threads is nil the number
|
||||
// of workers started is equal to the number of logical CPUs that are usable by
|
||||
// this process. If mining is already running, this method adjust the number of
|
||||
// threads allowed to use.
|
||||
func (api *PrivateMinerAPI) Start(threads *int) error {
|
||||
// Set the number of threads if the seal engine supports it
|
||||
if threads != nil {
|
||||
type threaded interface {
|
||||
SetThreads(threads int)
|
||||
}
|
||||
if th, ok := api.e.engine.(threaded); ok {
|
||||
log.Info("Updated mining threads", "threads", *threads)
|
||||
th.SetThreads(*threads)
|
||||
} else {
|
||||
log.Warn("Current seal engine isn't threaded")
|
||||
}
|
||||
}
|
||||
return err == nil, err
|
||||
// Start the miner and return
|
||||
if !api.e.IsMining() {
|
||||
return api.e.StartMining()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop the miner
|
||||
func (s *PrivateMinerAPI) Stop() bool {
|
||||
s.e.StopMining()
|
||||
func (api *PrivateMinerAPI) Stop() bool {
|
||||
api.e.StopMining()
|
||||
return true
|
||||
}
|
||||
|
||||
// SetExtra sets the extra data string that is included when this miner mines a block.
|
||||
func (s *PrivateMinerAPI) SetExtra(extra string) (bool, error) {
|
||||
if err := s.e.Miner().SetExtra([]byte(extra)); err != nil {
|
||||
func (api *PrivateMinerAPI) SetExtra(extra string) (bool, error) {
|
||||
if err := api.e.Miner().SetExtra([]byte(extra)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SetGasPrice sets the minimum accepted gas price for the miner.
|
||||
func (s *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
|
||||
s.e.Miner().SetGasPrice((*big.Int)(&gasPrice))
|
||||
func (api *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
|
||||
api.e.Miner().SetGasPrice((*big.Int)(&gasPrice))
|
||||
return true
|
||||
}
|
||||
|
||||
// SetEtherbase sets the etherbase of the miner
|
||||
func (s *PrivateMinerAPI) SetEtherbase(etherbase common.Address) bool {
|
||||
s.e.SetEtherbase(etherbase)
|
||||
func (api *PrivateMinerAPI) SetEtherbase(etherbase common.Address) bool {
|
||||
api.e.SetEtherbase(etherbase)
|
||||
return true
|
||||
}
|
||||
|
||||
// GetHashrate returns the current hashrate of the miner.
|
||||
func (s *PrivateMinerAPI) GetHashrate() uint64 {
|
||||
return uint64(s.e.miner.HashRate())
|
||||
func (api *PrivateMinerAPI) GetHashrate() uint64 {
|
||||
return uint64(api.e.miner.HashRate())
|
||||
}
|
||||
|
||||
// PrivateAdminAPI is the collection of Etheruem full node-related APIs
|
||||
@ -321,7 +333,7 @@ type TraceArgs struct {
|
||||
Timeout *string
|
||||
}
|
||||
|
||||
// TraceBlock processes the given block's RLP but does not import the block in to
|
||||
// TraceBlock processes the given block'api RLP but does not import the block in to
|
||||
// the chain.
|
||||
func (api *PrivateDebugAPI) TraceBlock(blockRlp []byte, config *vm.LogConfig) BlockTraceResult {
|
||||
var block types.Block
|
||||
@ -338,7 +350,7 @@ func (api *PrivateDebugAPI) TraceBlock(blockRlp []byte, config *vm.LogConfig) Bl
|
||||
}
|
||||
}
|
||||
|
||||
// TraceBlockFromFile loads the block's RLP from the given file name and attempts to
|
||||
// TraceBlockFromFile loads the block'api RLP from the given file name and attempts to
|
||||
// process it but does not import the block in to the chain.
|
||||
func (api *PrivateDebugAPI) TraceBlockFromFile(file string, config *vm.LogConfig) BlockTraceResult {
|
||||
blockRlp, err := ioutil.ReadFile(file)
|
||||
@ -395,8 +407,7 @@ func (api *PrivateDebugAPI) traceBlock(block *types.Block, logConfig *vm.LogConf
|
||||
Debug: true,
|
||||
Tracer: structLogger,
|
||||
}
|
||||
|
||||
if err := core.ValidateHeader(api.config, blockchain.AuxValidator(), block.Header(), blockchain.GetHeader(block.ParentHash(), block.NumberU64()-1), true, false); err != nil {
|
||||
if err := api.eth.engine.VerifyHeader(blockchain, block.Header(), true); err != nil {
|
||||
return false, structLogger.StructLogs(), err
|
||||
}
|
||||
statedb, err := blockchain.StateAt(blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1).Root())
|
||||
|
@ -22,10 +22,11 @@ import (
|
||||
"math/big"
|
||||
"regexp"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
@ -40,18 +41,9 @@ import (
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/pow"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
const (
|
||||
epochLength = 30000
|
||||
ethashRevision = 23
|
||||
|
||||
autoDAGcheckInterval = 10 * time.Hour
|
||||
autoDAGepochHeight = epochLength / 2
|
||||
)
|
||||
|
||||
var (
|
||||
datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
|
||||
portInUseErrRE = regexp.MustCompile("address already in use")
|
||||
@ -124,7 +116,7 @@ type Ethereum struct {
|
||||
chainDb ethdb.Database // Block chain database
|
||||
|
||||
eventMux *event.TypeMux
|
||||
pow pow.PoW
|
||||
engine consensus.Engine
|
||||
accountManager *accounts.Manager
|
||||
|
||||
ApiBackend *EthApiBackend
|
||||
@ -163,7 +155,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||
chainConfig: chainConfig,
|
||||
eventMux: ctx.EventMux,
|
||||
accountManager: ctx.AccountManager,
|
||||
pow: CreatePoW(ctx, config),
|
||||
engine: CreateConsensusEngine(ctx, config, chainConfig, chainDb),
|
||||
shutdownChan: make(chan bool),
|
||||
stopDbUpgrade: stopDbUpgrade,
|
||||
netVersionId: config.NetworkId,
|
||||
@ -186,7 +178,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||
}
|
||||
|
||||
vmConfig := vm.Config{EnablePreimageRecording: config.EnablePreimageRecording}
|
||||
eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.eventMux, vmConfig)
|
||||
eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.engine, eth.eventMux, vmConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -211,10 +203,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.FastSync, config.NetworkId, maxPeers, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil {
|
||||
if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.FastSync, config.NetworkId, maxPeers, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.pow)
|
||||
|
||||
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine)
|
||||
eth.miner.SetGasPrice(config.GasPrice)
|
||||
eth.miner.SetExtra(config.ExtraData)
|
||||
|
||||
@ -241,20 +234,20 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data
|
||||
return db, err
|
||||
}
|
||||
|
||||
// CreatePoW creates the required type of PoW instance for an Ethereum service
|
||||
func CreatePoW(ctx *node.ServiceContext, config *Config) pow.PoW {
|
||||
// CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service
|
||||
func CreateConsensusEngine(ctx *node.ServiceContext, config *Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine {
|
||||
switch {
|
||||
case config.PowFake:
|
||||
log.Warn("Ethash used in fake mode")
|
||||
return pow.FakePow{}
|
||||
return ethash.NewFaker()
|
||||
case config.PowTest:
|
||||
log.Warn("Ethash used in test mode")
|
||||
return pow.NewTestEthash()
|
||||
return ethash.NewTester()
|
||||
case config.PowShared:
|
||||
log.Warn("Ethash used in shared mode")
|
||||
return pow.NewSharedEthash()
|
||||
return ethash.NewShared()
|
||||
default:
|
||||
return pow.NewFullEthash(ctx.ResolvePath(config.EthashCacheDir), config.EthashCachesInMem, config.EthashCachesOnDisk,
|
||||
return ethash.New(ctx.ResolvePath(config.EthashCacheDir), config.EthashCachesInMem, config.EthashCachesOnDisk,
|
||||
config.EthashDatasetDir, config.EthashDatasetsInMem, config.EthashDatasetsOnDisk)
|
||||
}
|
||||
}
|
||||
@ -262,7 +255,13 @@ func CreatePoW(ctx *node.ServiceContext, config *Config) pow.PoW {
|
||||
// APIs returns the collection of RPC services the ethereum package offers.
|
||||
// NOTE, some of these services probably need to be moved to somewhere else.
|
||||
func (s *Ethereum) APIs() []rpc.API {
|
||||
return append(ethapi.GetAPIs(s.ApiBackend, s.solcPath), []rpc.API{
|
||||
apis := ethapi.GetAPIs(s.ApiBackend, s.solcPath)
|
||||
|
||||
// Append any APIs exposed explicitly by the consensus engine
|
||||
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
||||
|
||||
// Append all the local APIs and return
|
||||
return append(apis, []rpc.API{
|
||||
{
|
||||
Namespace: "eth",
|
||||
Version: "1.0",
|
||||
@ -332,13 +331,13 @@ func (self *Ethereum) SetEtherbase(etherbase common.Address) {
|
||||
self.miner.SetEtherbase(etherbase)
|
||||
}
|
||||
|
||||
func (s *Ethereum) StartMining(threads int) error {
|
||||
func (s *Ethereum) StartMining() error {
|
||||
eb, err := s.Etherbase()
|
||||
if err != nil {
|
||||
log.Error("Cannot start mining without etherbase", "err", err)
|
||||
return fmt.Errorf("etherbase missing: %v", err)
|
||||
}
|
||||
go s.miner.Start(eb, threads)
|
||||
go s.miner.Start(eb)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -350,7 +349,7 @@ func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager
|
||||
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
|
||||
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
|
||||
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
|
||||
func (s *Ethereum) Pow() pow.PoW { return s.pow }
|
||||
func (s *Ethereum) Engine() consensus.Engine { return s.engine }
|
||||
func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
|
||||
func (s *Ethereum) IsListening() bool { return true } // Always listening
|
||||
func (s *Ethereum) EthVersion() int { return int(s.protocolManager.SubProtocols[0].Version) }
|
||||
|
@ -52,8 +52,8 @@ type headerRequesterFn func(common.Hash) error
|
||||
// bodyRequesterFn is a callback type for sending a body retrieval request.
|
||||
type bodyRequesterFn func([]common.Hash) error
|
||||
|
||||
// blockValidatorFn is a callback type to verify a block's header for fast propagation.
|
||||
type blockValidatorFn func(block *types.Block, parent *types.Block) error
|
||||
// headerVerifierFn is a callback type to verify a block's header for fast propagation.
|
||||
type headerVerifierFn func(header *types.Header) error
|
||||
|
||||
// blockBroadcasterFn is a callback type for broadcasting a block to connected peers.
|
||||
type blockBroadcasterFn func(block *types.Block, propagate bool)
|
||||
@ -129,7 +129,7 @@ type Fetcher struct {
|
||||
|
||||
// Callbacks
|
||||
getBlock blockRetrievalFn // Retrieves a block from the local chain
|
||||
validateBlock blockValidatorFn // Checks if a block's headers have a valid proof of work
|
||||
verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
|
||||
broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers
|
||||
chainHeight chainHeightFn // Retrieves the current chain's height
|
||||
insertChain chainInsertFn // Injects a batch of blocks into the chain
|
||||
@ -144,7 +144,7 @@ type Fetcher struct {
|
||||
}
|
||||
|
||||
// New creates a block fetcher to retrieve blocks based on hash announcements.
|
||||
func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher {
|
||||
func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher {
|
||||
return &Fetcher{
|
||||
notify: make(chan *announce),
|
||||
inject: make(chan *inject),
|
||||
@ -162,7 +162,7 @@ func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlo
|
||||
queues: make(map[string]int),
|
||||
queued: make(map[common.Hash]*inject),
|
||||
getBlock: getBlock,
|
||||
validateBlock: validateBlock,
|
||||
verifyHeader: verifyHeader,
|
||||
broadcastBlock: broadcastBlock,
|
||||
chainHeight: chainHeight,
|
||||
insertChain: insertChain,
|
||||
@ -648,7 +648,7 @@ func (f *Fetcher) insert(peer string, block *types.Block) {
|
||||
return
|
||||
}
|
||||
// Quickly validate the header and propagate the block if it passes
|
||||
switch err := f.validateBlock(block, parent); err {
|
||||
switch err := f.verifyHeader(block.Header()); err {
|
||||
case nil:
|
||||
// All ok, quickly propagate to our peers
|
||||
propBroadcastOutTimer.UpdateSince(block.ReceivedAt)
|
||||
|
@ -91,7 +91,7 @@ func newTester() *fetcherTester {
|
||||
blocks: map[common.Hash]*types.Block{genesis.Hash(): genesis},
|
||||
drops: make(map[string]bool),
|
||||
}
|
||||
tester.fetcher = New(tester.getBlock, tester.verifyBlock, tester.broadcastBlock, tester.chainHeight, tester.insertChain, tester.dropPeer)
|
||||
tester.fetcher = New(tester.getBlock, tester.verifyHeader, tester.broadcastBlock, tester.chainHeight, tester.insertChain, tester.dropPeer)
|
||||
tester.fetcher.Start()
|
||||
|
||||
return tester
|
||||
@ -105,8 +105,8 @@ func (f *fetcherTester) getBlock(hash common.Hash) *types.Block {
|
||||
return f.blocks[hash]
|
||||
}
|
||||
|
||||
// verifyBlock is a nop placeholder for the block header verification.
|
||||
func (f *fetcherTester) verifyBlock(block *types.Block, parent *types.Block) error {
|
||||
// verifyHeader is a nop placeholder for the block header verification.
|
||||
func (f *fetcherTester) verifyHeader(header *types.Header) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
@ -37,7 +39,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/pow"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
@ -97,7 +98,7 @@ type ProtocolManager struct {
|
||||
|
||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||
// with the ethereum network.
|
||||
func NewProtocolManager(config *params.ChainConfig, fastSync bool, networkId int, maxPeers int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
||||
func NewProtocolManager(config *params.ChainConfig, fastSync bool, networkId int, maxPeers int, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
||||
// Create the protocol manager with the base fields
|
||||
manager := &ProtocolManager{
|
||||
networkId: networkId,
|
||||
@ -165,8 +166,8 @@ func NewProtocolManager(config *params.ChainConfig, fastSync bool, networkId int
|
||||
blockchain.GetTdByHash, blockchain.InsertHeaderChain, manager.insertChain, blockchain.InsertReceiptChain, blockchain.Rollback,
|
||||
manager.removePeer)
|
||||
|
||||
validator := func(block *types.Block, parent *types.Block) error {
|
||||
return core.ValidateHeader(config, pow, block.Header(), parent.Header(), true, false)
|
||||
validator := func(header *types.Header) error {
|
||||
return engine.VerifyHeader(blockchain, header, true)
|
||||
}
|
||||
heighter := func() uint64 {
|
||||
return blockchain.CurrentBlock().NumberU64()
|
||||
@ -448,7 +449,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||
p.forkDrop = nil
|
||||
|
||||
// Validate the header and either drop the peer or continue
|
||||
if err := core.ValidateDAOHeaderExtraData(pm.chainconfig, headers[0]); err != nil {
|
||||
if err := misc.VerifyDAOHeaderExtraData(pm.chainconfig, headers[0]); err != nil {
|
||||
p.Log().Debug("Verified to be on the other side of the DAO fork, dropping")
|
||||
return err
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
@ -34,7 +35,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/pow"
|
||||
)
|
||||
|
||||
var bigTxGas = new(big.Int).SetUint64(params.TxGas)
|
||||
@ -469,7 +469,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
||||
// Create a DAO aware protocol manager
|
||||
var (
|
||||
evmux = new(event.TypeMux)
|
||||
pow = new(pow.FakePow)
|
||||
pow = ethash.NewFaker()
|
||||
db, _ = ethdb.NewMemDatabase()
|
||||
config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
||||
gspec = &core.Genesis{Config: config}
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
@ -37,7 +38,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/pow"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -50,22 +50,22 @@ var (
|
||||
// channels for different events.
|
||||
func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) {
|
||||
var (
|
||||
evmux = new(event.TypeMux)
|
||||
pow = new(pow.FakePow)
|
||||
db, _ = ethdb.NewMemDatabase()
|
||||
gspec = &core.Genesis{
|
||||
evmux = new(event.TypeMux)
|
||||
engine = ethash.NewFaker()
|
||||
db, _ = ethdb.NewMemDatabase()
|
||||
gspec = &core.Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}},
|
||||
}
|
||||
genesis = gspec.MustCommit(db)
|
||||
blockchain, _ = core.NewBlockChain(db, gspec.Config, pow, evmux, vm.Config{})
|
||||
blockchain, _ = core.NewBlockChain(db, gspec.Config, engine, evmux, vm.Config{})
|
||||
)
|
||||
chain, _ := core.GenerateChain(gspec.Config, genesis, db, blocks, generator)
|
||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pm, err := NewProtocolManager(gspec.Config, fastSync, NetworkId, 1000, evmux, &testTxPool{added: newtx}, pow, blockchain, db)
|
||||
pm, err := NewProtocolManager(gspec.Config, fastSync, NetworkId, 1000, evmux, &testTxPool{added: newtx}, engine, blockchain, db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user