Skip to content

Commit

Permalink
miner: refactor the miner, make the pending block on demand (#28623)
Browse files Browse the repository at this point in the history
* miner: untangle miner

* miner: use common.hash instead of *types.header

* cmd/geth: deprecate --mine

* eth: get rid of most miner api

* console: get rid of coinbase in welcome message

* miner/stress: get rid of the miner stress test

* eth: get rid of miner.setEtherbase

* ethstats: remove miner and hashrate flags

* ethstats: remove miner and hashrate flags

* cmd: rename pendingBlockProducer to miner.pending.feeRecipient flag

* miner: use pendingFeeRecipient instead of etherbase

* miner: add mutex to protect the pending block

* miner: add mutex to protect the pending block

* eth: get rid of etherbase mentions

* miner: no need to lock the coinbase

* eth, miner: fix linter

---------

Co-authored-by: Martin Holst Swende <[email protected]>
Co-authored-by: Péter Szilágyi <[email protected]>
  • Loading branch information
3 people authored Mar 6, 2024
1 parent 6e379b6 commit d8e0807
Show file tree
Hide file tree
Showing 35 changed files with 598 additions and 2,488 deletions.
3 changes: 0 additions & 3 deletions cmd/geth/consolecmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ func TestConsoleWelcome(t *testing.T) {
Welcome to the Geth JavaScript console!
instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
coinbase: {{.Etherbase}}
at block: 0 ({{niltime}})
datadir: {{.Datadir}}
modules: {{apis}}
Expand Down Expand Up @@ -131,7 +130,6 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) {
attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH })
attach.SetTemplateFunc("gover", runtime.Version)
attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase })
attach.SetTemplateFunc("niltime", func() string {
return time.Unix(1548854791, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
})
Expand All @@ -144,7 +142,6 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) {
Welcome to the Geth JavaScript console!
instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
coinbase: {{etherbase}}
at block: 0 ({{niltime}}){{if ipc}}
datadir: {{datadir}}{{end}}
modules: {{apis}}
Expand Down
26 changes: 4 additions & 22 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/internal/debug"
Expand Down Expand Up @@ -116,13 +115,14 @@ var (
utils.DiscoveryPortFlag,
utils.MaxPeersFlag,
utils.MaxPendingPeersFlag,
utils.MiningEnabledFlag,
utils.MiningEnabledFlag, // deprecated
utils.MinerGasLimitFlag,
utils.MinerGasPriceFlag,
utils.MinerEtherbaseFlag,
utils.MinerEtherbaseFlag, // deprecated
utils.MinerExtraDataFlag,
utils.MinerRecommitIntervalFlag,
utils.MinerNewPayloadTimeout,
utils.MinerPendingFeeRecipientFlag,
utils.MinerNewPayloadTimeoutFlag, // deprecated
utils.NATFlag,
utils.NoDiscoverFlag,
utils.DiscoveryV4Flag,
Expand Down Expand Up @@ -421,24 +421,6 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
}
}()
}

// Start auxiliary services if enabled
if ctx.Bool(utils.MiningEnabledFlag.Name) {
// Mining only makes sense if a full Ethereum node is running
if ctx.String(utils.SyncModeFlag.Name) == "light" {
utils.Fatalf("Light clients do not support mining")
}
ethBackend, ok := backend.(*eth.EthAPIBackend)
if !ok {
utils.Fatalf("Ethereum service not running")
}
// Set the gas price to the limits from the CLI and start mining
gasprice := flags.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
ethBackend.TxPool().SetGasTip(gasprice)
if err := ethBackend.StartMining(); err != nil {
utils.Fatalf("Failed to start mining: %v", err)
}
}
}

// unlockAccounts unlocks any account specifically requested.
Expand Down
43 changes: 20 additions & 23 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,6 @@ var (
}

// Miner settings
MiningEnabledFlag = &cli.BoolFlag{
Name: "mine",
Usage: "Enable mining",
Category: flags.MinerCategory,
}
MinerGasLimitFlag = &cli.Uint64Flag{
Name: "miner.gaslimit",
Usage: "Target gas ceiling for mined blocks",
Expand All @@ -442,11 +437,6 @@ var (
Value: ethconfig.Defaults.Miner.GasPrice,
Category: flags.MinerCategory,
}
MinerEtherbaseFlag = &cli.StringFlag{
Name: "miner.etherbase",
Usage: "0x prefixed public address for block mining rewards",
Category: flags.MinerCategory,
}
MinerExtraDataFlag = &cli.StringFlag{
Name: "miner.extradata",
Usage: "Block extra data set by the miner (default = client version)",
Expand All @@ -458,10 +448,9 @@ var (
Value: ethconfig.Defaults.Miner.Recommit,
Category: flags.MinerCategory,
}
MinerNewPayloadTimeout = &cli.DurationFlag{
Name: "miner.newpayload-timeout",
Usage: "Specify the maximum time allowance for creating a new payload",
Value: ethconfig.Defaults.Miner.NewPayloadTimeout,
MinerPendingFeeRecipientFlag = &cli.StringFlag{
Name: "miner.pending.feeRecipient",
Usage: "0x prefixed public address for the pending block producer (not used for actual block production)",
Category: flags.MinerCategory,
}

Expand Down Expand Up @@ -1268,19 +1257,23 @@ func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error

// setEtherbase retrieves the etherbase from the directly specified command line flags.
func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
if !ctx.IsSet(MinerEtherbaseFlag.Name) {
if ctx.IsSet(MinerEtherbaseFlag.Name) {
log.Warn("Option --miner.etherbase is deprecated as the etherbase is set by the consensus client post-merge")
return
}
addr := ctx.String(MinerEtherbaseFlag.Name)
if !ctx.IsSet(MinerPendingFeeRecipientFlag.Name) {
return
}
addr := ctx.String(MinerPendingFeeRecipientFlag.Name)
if strings.HasPrefix(addr, "0x") || strings.HasPrefix(addr, "0X") {
addr = addr[2:]
}
b, err := hex.DecodeString(addr)
if err != nil || len(b) != common.AddressLength {
Fatalf("-%s: invalid etherbase address %q", MinerEtherbaseFlag.Name, addr)
Fatalf("-%s: invalid pending block producer address %q", MinerPendingFeeRecipientFlag.Name, addr)
return
}
cfg.Miner.Etherbase = common.BytesToAddress(b)
cfg.Miner.PendingFeeRecipient = common.BytesToAddress(b)
}

// MakePasswordList reads password lines from the file specified by the global --password flag.
Expand Down Expand Up @@ -1496,6 +1489,9 @@ func setTxPool(ctx *cli.Context, cfg *legacypool.Config) {
}

func setMiner(ctx *cli.Context, cfg *miner.Config) {
if ctx.Bool(MiningEnabledFlag.Name) {
log.Warn("The flag --mine is deprecated and will be removed")
}
if ctx.IsSet(MinerExtraDataFlag.Name) {
cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name))
}
Expand All @@ -1508,8 +1504,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
if ctx.IsSet(MinerRecommitIntervalFlag.Name) {
cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
}
if ctx.IsSet(MinerNewPayloadTimeout.Name) {
cfg.NewPayloadTimeout = ctx.Duration(MinerNewPayloadTimeout.Name)
if ctx.IsSet(MinerNewPayloadTimeoutFlag.Name) {
log.Warn("The flag --miner.newpayload-timeout is deprecated and will be removed, please use --miner.recommit")
cfg.Recommit = ctx.Duration(MinerNewPayloadTimeoutFlag.Name)
}
}

Expand Down Expand Up @@ -1786,8 +1783,8 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {

// Figure out the dev account address.
// setEtherbase has been called above, configuring the miner address from command line flags.
if cfg.Miner.Etherbase != (common.Address{}) {
developer = accounts.Account{Address: cfg.Miner.Etherbase}
if cfg.Miner.PendingFeeRecipient != (common.Address{}) {
developer = accounts.Account{Address: cfg.Miner.PendingFeeRecipient}
} else if accs := ks.Accounts(); len(accs) > 0 {
developer = ks.Accounts()[0]
} else {
Expand All @@ -1798,7 +1795,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
// Make sure the address is configured as fee recipient, otherwise
// the miner will fail to start.
cfg.Miner.Etherbase = developer.Address
cfg.Miner.PendingFeeRecipient = developer.Address

if err := ks.Unlock(developer, passphrase); err != nil {
Fatalf("Failed to unlock developer account: %v", err)
Expand Down
20 changes: 20 additions & 0 deletions cmd/utils/flags_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ var DeprecatedFlags = []cli.Flag{
LightNoSyncServeFlag,
LogBacktraceAtFlag,
LogDebugFlag,
MinerNewPayloadTimeoutFlag,
MinerEtherbaseFlag,
MiningEnabledFlag,
}

var (
Expand Down Expand Up @@ -132,6 +135,23 @@ var (
Usage: "Prepends log messages with call-site location (deprecated)",
Category: flags.DeprecatedCategory,
}
// Deprecated February 2024
MinerNewPayloadTimeoutFlag = &cli.DurationFlag{
Name: "miner.newpayload-timeout",
Usage: "Specify the maximum time allowance for creating a new payload",
Value: ethconfig.Defaults.Miner.Recommit,
Category: flags.MinerCategory,
}
MinerEtherbaseFlag = &cli.StringFlag{
Name: "miner.etherbase",
Usage: "0x prefixed public address for block mining rewards",
Category: flags.MinerCategory,
}
MiningEnabledFlag = &cli.BoolFlag{
Name: "mine",
Usage: "Enable mining",
Category: flags.MinerCategory,
}
)

// showDeprecated displays deprecated flags that will be soon removed from the codebase.
Expand Down
8 changes: 0 additions & 8 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,3 @@ type Engine interface {
// Close terminates any background threads maintained by the consensus engine.
Close() error
}

// PoW is a consensus engine based on proof-of-work.
type PoW interface {
Engine

// Hashrate returns the current mining hashrate of a PoW consensus engine.
Hashrate() float64
}
3 changes: 0 additions & 3 deletions console/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,6 @@ func (c *Console) Welcome() {
// Print some generic Geth metadata
if res, err := c.jsre.Run(`
var message = "instance: " + web3.version.node + "\n";
try {
message += "coinbase: " + eth.coinbase + "\n";
} catch (err) {}
message += "at block: " + eth.blockNumber + " (" + new Date(1000 * eth.getBlock(eth.blockNumber).timestamp) + ")\n";
try {
message += " datadir: " + admin.datadir + "\n";
Expand Down
5 changes: 1 addition & 4 deletions console/console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester {
ethConf := &ethconfig.Config{
Genesis: core.DeveloperGenesisBlock(11_500_000, nil),
Miner: miner.Config{
Etherbase: common.HexToAddress(testAddress),
PendingFeeRecipient: common.HexToAddress(testAddress),
},
}
if confOverride != nil {
Expand Down Expand Up @@ -167,9 +167,6 @@ func TestWelcome(t *testing.T) {
if want := fmt.Sprintf("instance: %s", testInstance); !strings.Contains(output, want) {
t.Fatalf("console output missing instance: have\n%s\nwant also %s", output, want)
}
if want := fmt.Sprintf("coinbase: %s", testAddress); !strings.Contains(output, want) {
t.Fatalf("console output missing coinbase: have\n%s\nwant also %s", output, want)
}
if want := "at block: 0"; !strings.Contains(output, want) {
t.Fatalf("console output missing sync status: have\n%s\nwant also %s", output, want)
}
Expand Down
52 changes: 0 additions & 52 deletions eth/api.go

This file was deleted.

23 changes: 5 additions & 18 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import (
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
Expand Down Expand Up @@ -67,7 +66,7 @@ func (b *EthAPIBackend) SetHead(number uint64) {
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
// Pending block is only known by the miner
if number == rpc.PendingBlockNumber {
block := b.eth.miner.PendingBlock()
block, _, _ := b.eth.miner.Pending()
if block == nil {
return nil, errors.New("pending block is not available")
}
Expand Down Expand Up @@ -118,7 +117,7 @@ func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*ty
func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
// Pending block is only known by the miner
if number == rpc.PendingBlockNumber {
block := b.eth.miner.PendingBlock()
block, _, _ := b.eth.miner.Pending()
if block == nil {
return nil, errors.New("pending block is not available")
}
Expand Down Expand Up @@ -182,14 +181,14 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r
return nil, errors.New("invalid arguments; neither block nor hash specified")
}

func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
return b.eth.miner.PendingBlockAndReceipts()
func (b *EthAPIBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) {
return b.eth.miner.Pending()
}

func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
// Pending state is only known by the miner
if number == rpc.PendingBlockNumber {
block, state := b.eth.miner.Pending()
block, _, state := b.eth.miner.Pending()
if block == nil || state == nil {
return nil, nil, errors.New("pending state is not available")
}
Expand Down Expand Up @@ -267,10 +266,6 @@ func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEven
return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch)
}

func (b *EthAPIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
return b.eth.miner.SubscribePendingLogs(ch)
}

func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
return b.eth.BlockChain().SubscribeChainEvent(ch)
}
Expand Down Expand Up @@ -421,14 +416,6 @@ func (b *EthAPIBackend) CurrentHeader() *types.Header {
return b.eth.blockchain.CurrentHeader()
}

func (b *EthAPIBackend) Miner() *miner.Miner {
return b.eth.Miner()
}

func (b *EthAPIBackend) StartMining() error {
return b.eth.StartMining()
}

func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, tracers.StateReleaseFunc, error) {
return b.eth.stateAtBlock(ctx, block, reexec, base, readOnly, preferDisk)
}
Expand Down
4 changes: 2 additions & 2 deletions eth/api_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
// If we're dumping the pending state, we need to request
// both the pending block as well as the pending state from
// the miner and operate on those
_, stateDb := api.eth.miner.Pending()
_, _, stateDb := api.eth.miner.Pending()
if stateDb == nil {
return state.Dump{}, errors.New("pending state is not available")
}
Expand Down Expand Up @@ -142,7 +142,7 @@ func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hex
// If we're dumping the pending state, we need to request
// both the pending block as well as the pending state from
// the miner and operate on those
_, stateDb = api.eth.miner.Pending()
_, _, stateDb = api.eth.miner.Pending()
if stateDb == nil {
return state.Dump{}, errors.New("pending state is not available")
}
Expand Down
Loading

0 comments on commit d8e0807

Please sign in to comment.