Skip to content

eth/backend.go

Type MOD
Upstream Lines 601
Changed +50 -11

Wire ethash engine, MESS, and PoW sync into eth.Ethereum

diff --git a/eth/backend.go b/eth/backend.go
index af8b04bda..e1149fb6d 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -172,13 +172,29 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
        }
    }

+   // One-shot migration of a datadir created by core-geth: it stores the chain
+   // config under the same key but in a different JSON schema, which would otherwise
+   // trip CheckCompatible and rewind the chain. This rewrites it in place on the
+   // first start; afterwards it is a no-op. Safe to remove together with
+   // core/coregeth_migration.go once core-geth is deprecated.
+   if err := core.MigrateCoreGethChainConfig(chainDb); err != nil {
+       return nil, err
+   }
+
    // Here we determine genesis hash and active ChainConfig.
    // We need these to figure out the consensus parameters and to set up history pruning.
    chainConfig, genesisHash, err := core.LoadChainConfig(chainDb, config.Genesis)
    if err != nil {
        return nil, err
    }
-   engine, err := ethconfig.CreateConsensusEngine(chainConfig, chainDb)
+   // Resolve ethash cache directory relative to datadir (pre-purge3: stack.ResolvePath).
+   // Without this, the relative "etchash" path is created in CWD (e.g. / under systemd).
+   config.Ethash.CacheDir = stack.ResolvePath(config.Ethash.CacheDir)
+   // Transfer the miner-side notify settings into the ethash config so
+   // --miner.notify / --miner.notify.full / --miner.noverify actually reach
+   // the underlying engine (mirrors the pre-purge plumbing).
+   config.Ethash.NotifyFull = config.Miner.NotifyFull
+   engine, err := ethconfig.CreateConsensusEngineWithConfig(chainConfig, chainDb, config.Ethash, config.Miner.Notify, config.Miner.Noverify)
    if err != nil {
        return nil, err
    }
@@ -334,21 +350,29 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
    // Permit the downloader to use the trie cache allowance during fast sync
    cacheLimit := options.TrieCleanLimit + options.TrieDirtyLimit + options.SnapshotLimit
    if eth.handler, err = newHandler(&handlerConfig{
-       NodeID:         eth.p2pServer.Self().ID(),
-       Database:       chainDb,
-       Chain:          eth.blockchain,
-       TxPool:         eth.txPool,
-       Network:        networkID,
-       Sync:           config.SyncMode,
-       BloomCache:     uint64(cacheLimit),
-       RequiredBlocks: config.RequiredBlocks,
+       NodeID:           eth.p2pServer.Self().ID(),
+       Database:         chainDb,
+       Chain:            eth.blockchain,
+       TxPool:           eth.txPool,
+       Network:          networkID,
+       Sync:             config.SyncMode,
+       BloomCache:       uint64(cacheLimit),
+       RequiredBlocks:   config.RequiredBlocks,
+       IsPow:            eth.blockchain.Config().IsPow(),
+       MESSForceEnable:  config.MESSForceEnable,
+       MESSForceDisable: config.MESSForceDisable,
    }); err != nil {
        return nil, err
    }

    eth.dropper = newDropper(eth.p2pServer.MaxDialedConns(), eth.p2pServer.MaxInboundConns())

-   eth.miner = miner.New(eth, config.Miner, eth.engine)
+   if chainConfig.IsPow() {
+       eth.miner = miner.NewPoW(eth, config.Miner, eth.engine, eth.handler.EventMux())
+       go eth.minerUpdate()
+   } else {
+       eth.miner = miner.New(eth, config.Miner, eth.engine)
+   }
    eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))
    eth.miner.SetPrioAddresses(config.TxPool.Locals)

@@ -394,9 +418,21 @@ func makeExtraData(extra []byte) []byte {
 func (s *Ethereum) APIs() []rpc.API {
    apis := ethapi.GetAPIs(s.APIBackend)

+   // Register ethash engine APIs (eth_getWork, eth_submitWork, etc.) if available.
+   // Removed from consensus.Engine interface in upstream; restored for PoW chains.
+   type engineAPIs interface {
+       APIs(consensus.ChainHeaderReader) []rpc.API
+   }
+   if ea, ok := s.engine.(engineAPIs); ok {
+       apis = append(apis, ea.APIs(s.blockchain)...)
+   }
+
    // Append all the local APIs and return
    return append(apis, []rpc.API{
        {
+           Namespace: "eth",
+           Service:   NewEthereumAPI(s),
+       }, {
            Namespace: "miner",
            Service:   NewMinerAPI(s),
        }, {
@@ -436,7 +472,7 @@ func (s *Ethereum) ArchiveMode() bool                  { return s.config.NoPruni
 // Protocols returns all the currently configured
 // network protocols to start.
 func (s *Ethereum) Protocols() []p2p.Protocol {
-   protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.discmix)
+   protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.discmix, eth.GetProtocolVersions(s.blockchain.Config().IsPow()))
    if s.config.SnapshotCache > 0 {
        protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler))...)
    }
@@ -578,6 +614,9 @@ func (s *Ethereum) setupDiscovery() error {
 // Stop implements node.Lifecycle, terminating all internal goroutines used by the
 // Ethereum protocol.
 func (s *Ethereum) Stop() error {
+   // Stop PoW miner if running.
+   s.miner.CloseMining()
+
    // Stop all the peer-related stuff first.
    s.discmix.Close()
    s.dropper.Stop()

← Back to Eth Service