Skip to content

Commit 2b44ef5

Browse files
authored
miner, cmd, eth: require explicit etherbase address (ethereum#26413)
This change introduces a breaking change to miner.etherbase is configured. Previously, users did not need to explicitly set the etherbase address via flag, since 'first' local account was used as etherbase automatically. This change removes the "default first account" feature. In Proof-of-stake world, the fee recipient address is provided by CL, and not configured in Geth any more - meaning that miner.etherbase is mostly for legacy networks(pow, clique networks etc).
1 parent 4f4a25d commit 2b44ef5

File tree

6 files changed

+63
-75
lines changed

6 files changed

+63
-75
lines changed

cmd/geth/les_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func startLightServer(t *testing.T) *gethrpc {
146146
t.Logf("Importing keys to geth")
147147
runGeth(t, "account", "import", "--datadir", datadir, "--password", "./testdata/password.txt", "--lightkdf", "./testdata/key.prv").WaitExit()
148148
account := "0x02f0d131f1f97aef08aec6e3291b957d9efe7105"
149-
server := startGethWithIpc(t, "lightserver", "--allow-insecure-unlock", "--datadir", datadir, "--password", "./testdata/password.txt", "--unlock", account, "--mine", "--light.serve=100", "--light.maxpeers=1", "--nodiscover", "--nat=extip:127.0.0.1", "--verbosity=4")
149+
server := startGethWithIpc(t, "lightserver", "--allow-insecure-unlock", "--datadir", datadir, "--password", "./testdata/password.txt", "--unlock", account, "--miner.etherbase=0x02f0d131f1f97aef08aec6e3291b957d9efe7105", "--mine", "--light.serve=100", "--light.maxpeers=1", "--nodiscover", "--nat=extip:127.0.0.1", "--verbosity=4")
150150
return server
151151
}
152152

cmd/utils/flags.go

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,7 @@ var (
538538
}
539539
MinerEtherbaseFlag = &cli.StringFlag{
540540
Name: "miner.etherbase",
541-
Usage: "Public address for block mining rewards (default = first account)",
542-
Value: "0",
541+
Usage: "0x prefixed public address for block mining rewards",
543542
Category: flags.MinerCategory,
544543
}
545544
MinerExtraDataFlag = &cli.StringFlag{
@@ -1343,25 +1342,15 @@ func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error
13431342
return accs[index], nil
13441343
}
13451344

1346-
// setEtherbase retrieves the etherbase either from the directly specified
1347-
// command line flags or from the keystore if CLI indexed.
1348-
func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *ethconfig.Config) {
1349-
// Extract the current etherbase
1350-
var etherbase string
1345+
// setEtherbase retrieves the etherbase from the directly specified command line flags.
1346+
func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
13511347
if ctx.IsSet(MinerEtherbaseFlag.Name) {
1352-
etherbase = ctx.String(MinerEtherbaseFlag.Name)
1353-
}
1354-
// Convert the etherbase into an address and configure it
1355-
if etherbase != "" {
1356-
if ks != nil {
1357-
account, err := MakeAddress(ks, etherbase)
1358-
if err != nil {
1359-
Fatalf("Invalid miner etherbase: %v", err)
1360-
}
1361-
cfg.Miner.Etherbase = account.Address
1362-
} else {
1363-
Fatalf("No etherbase configured")
1348+
b, err := hexutil.Decode(ctx.String(MinerEtherbaseFlag.Name))
1349+
if err != nil || len(b) != common.AddressLength {
1350+
log.Info("Failed to decode etherbase", "err", err)
1351+
return
13641352
}
1353+
cfg.Miner.Etherbase = common.BytesToAddress(b)
13651354
}
13661355
}
13671356

@@ -1739,11 +1728,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17391728
if ctx.IsSet(LightServeFlag.Name) && ctx.Uint64(TxLookupLimitFlag.Name) != 0 {
17401729
log.Warn("LES server cannot serve old transaction status and cannot connect below les/4 protocol version if transaction lookup index is limited")
17411730
}
1742-
var ks *keystore.KeyStore
1743-
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
1744-
ks = keystores[0].(*keystore.KeyStore)
1745-
}
1746-
setEtherbase(ctx, ks, cfg)
1731+
setEtherbase(ctx, cfg)
17471732
setGPO(ctx, &cfg.GPO, ctx.String(SyncModeFlag.Name) == "light")
17481733
setTxPool(ctx, &cfg.TxPool)
17491734
setEthash(ctx, cfg)
@@ -1921,6 +1906,14 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
19211906
// when we're definitely concerned with only one account.
19221907
passphrase = list[0]
19231908
}
1909+
// Unlock the developer account by local keystore.
1910+
var ks *keystore.KeyStore
1911+
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
1912+
ks = keystores[0].(*keystore.KeyStore)
1913+
}
1914+
if ks == nil {
1915+
Fatalf("Keystore is not available")
1916+
}
19241917
// setEtherbase has been called above, configuring the miner address from command line flags.
19251918
if cfg.Miner.Etherbase != (common.Address{}) {
19261919
developer = accounts.Account{Address: cfg.Miner.Etherbase}

eth/backend.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,18 +329,6 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) {
329329
if etherbase != (common.Address{}) {
330330
return etherbase, nil
331331
}
332-
if wallets := s.AccountManager().Wallets(); len(wallets) > 0 {
333-
if accounts := wallets[0].Accounts(); len(accounts) > 0 {
334-
etherbase := accounts[0].Address
335-
336-
s.lock.Lock()
337-
s.etherbase = etherbase
338-
s.lock.Unlock()
339-
340-
log.Info("Etherbase automatically configured", "address", etherbase)
341-
return etherbase, nil
342-
}
343-
}
344332
return common.Address{}, fmt.Errorf("etherbase must be explicitly specified")
345333
}
346334

@@ -456,7 +444,7 @@ func (s *Ethereum) StartMining(threads int) error {
456444
// introduced to speed sync times.
457445
atomic.StoreUint32(&s.handler.acceptTxs, 1)
458446

459-
go s.miner.Start(eb)
447+
go s.miner.Start()
460448
}
461449
return nil
462450
}

miner/miner.go

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type Backend interface {
4545

4646
// Config is the configuration parameters of mining.
4747
type Config struct {
48-
Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards (default = first account)
48+
Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards
4949
Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages (only useful in ethash).
5050
NotifyFull bool `toml:",omitempty"` // Notify with pending block headers instead of work packages
5151
ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner
@@ -73,25 +73,24 @@ var DefaultConfig = Config{
7373

7474
// Miner creates blocks and searches for proof-of-work values.
7575
type Miner struct {
76-
mux *event.TypeMux
77-
worker *worker
78-
coinbase common.Address
79-
eth Backend
80-
engine consensus.Engine
81-
exitCh chan struct{}
82-
startCh chan common.Address
83-
stopCh chan struct{}
76+
mux *event.TypeMux
77+
eth Backend
78+
engine consensus.Engine
79+
exitCh chan struct{}
80+
startCh chan struct{}
81+
stopCh chan struct{}
82+
worker *worker
8483

8584
wg sync.WaitGroup
8685
}
8786

8887
func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(header *types.Header) bool) *Miner {
8988
miner := &Miner{
90-
eth: eth,
9189
mux: mux,
90+
eth: eth,
9291
engine: engine,
9392
exitCh: make(chan struct{}),
94-
startCh: make(chan common.Address),
93+
startCh: make(chan struct{}),
9594
stopCh: make(chan struct{}),
9695
worker: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock, true),
9796
}
@@ -138,20 +137,17 @@ func (miner *Miner) update() {
138137
case downloader.FailedEvent:
139138
canStart = true
140139
if shouldStart {
141-
miner.SetEtherbase(miner.coinbase)
142140
miner.worker.start()
143141
}
144142
case downloader.DoneEvent:
145143
canStart = true
146144
if shouldStart {
147-
miner.SetEtherbase(miner.coinbase)
148145
miner.worker.start()
149146
}
150147
// Stop reacting to downloader events
151148
events.Unsubscribe()
152149
}
153-
case addr := <-miner.startCh:
154-
miner.SetEtherbase(addr)
150+
case <-miner.startCh:
155151
if canStart {
156152
miner.worker.start()
157153
}
@@ -166,8 +162,8 @@ func (miner *Miner) update() {
166162
}
167163
}
168164

169-
func (miner *Miner) Start(coinbase common.Address) {
170-
miner.startCh <- coinbase
165+
func (miner *Miner) Start() {
166+
miner.startCh <- struct{}{}
171167
}
172168

173169
func (miner *Miner) Stop() {
@@ -223,7 +219,6 @@ func (miner *Miner) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
223219
}
224220

225221
func (miner *Miner) SetEtherbase(addr common.Address) {
226-
miner.coinbase = addr
227222
miner.worker.setEtherbase(addr)
228223
}
229224

miner/miner_test.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
8686
func TestMiner(t *testing.T) {
8787
miner, mux, cleanup := createMiner(t)
8888
defer cleanup(false)
89-
miner.Start(common.HexToAddress("0x12345"))
89+
90+
miner.Start()
9091
waitForMiningState(t, miner, true)
9192
// Start the downloader
9293
mux.Post(downloader.StartEvent{})
@@ -114,7 +115,8 @@ func TestMiner(t *testing.T) {
114115
func TestMinerDownloaderFirstFails(t *testing.T) {
115116
miner, mux, cleanup := createMiner(t)
116117
defer cleanup(false)
117-
miner.Start(common.HexToAddress("0x12345"))
118+
119+
miner.Start()
118120
waitForMiningState(t, miner, true)
119121
// Start the downloader
120122
mux.Post(downloader.StartEvent{})
@@ -146,7 +148,8 @@ func TestMinerDownloaderFirstFails(t *testing.T) {
146148
func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
147149
miner, mux, cleanup := createMiner(t)
148150
defer cleanup(false)
149-
miner.Start(common.HexToAddress("0x12345"))
151+
152+
miner.Start()
150153
waitForMiningState(t, miner, true)
151154
// Start the downloader
152155
mux.Post(downloader.StartEvent{})
@@ -159,7 +162,7 @@ func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
159162
miner.Stop()
160163
waitForMiningState(t, miner, false)
161164

162-
miner.Start(common.HexToAddress("0x678910"))
165+
miner.Start()
163166
waitForMiningState(t, miner, true)
164167

165168
miner.Stop()
@@ -170,21 +173,21 @@ func TestStartWhileDownload(t *testing.T) {
170173
miner, mux, cleanup := createMiner(t)
171174
defer cleanup(false)
172175
waitForMiningState(t, miner, false)
173-
miner.Start(common.HexToAddress("0x12345"))
176+
miner.Start()
174177
waitForMiningState(t, miner, true)
175178
// Stop the downloader and wait for the update loop to run
176179
mux.Post(downloader.StartEvent{})
177180
waitForMiningState(t, miner, false)
178181
// Starting the miner after the downloader should not work
179-
miner.Start(common.HexToAddress("0x12345"))
182+
miner.Start()
180183
waitForMiningState(t, miner, false)
181184
}
182185

183186
func TestStartStopMiner(t *testing.T) {
184187
miner, _, cleanup := createMiner(t)
185188
defer cleanup(false)
186189
waitForMiningState(t, miner, false)
187-
miner.Start(common.HexToAddress("0x12345"))
190+
miner.Start()
188191
waitForMiningState(t, miner, true)
189192
miner.Stop()
190193
waitForMiningState(t, miner, false)
@@ -194,7 +197,7 @@ func TestCloseMiner(t *testing.T) {
194197
miner, _, cleanup := createMiner(t)
195198
defer cleanup(true)
196199
waitForMiningState(t, miner, false)
197-
miner.Start(common.HexToAddress("0x12345"))
200+
miner.Start()
198201
waitForMiningState(t, miner, true)
199202
// Terminate the miner and wait for the update loop to run
200203
miner.Close()
@@ -206,21 +209,21 @@ func TestCloseMiner(t *testing.T) {
206209
func TestMinerSetEtherbase(t *testing.T) {
207210
miner, mux, cleanup := createMiner(t)
208211
defer cleanup(false)
209-
// Start with a 'bad' mining address
210-
miner.Start(common.HexToAddress("0xdead"))
212+
miner.Start()
211213
waitForMiningState(t, miner, true)
212214
// Start the downloader
213215
mux.Post(downloader.StartEvent{})
214216
waitForMiningState(t, miner, false)
215217
// Now user tries to configure proper mining address
216-
miner.Start(common.HexToAddress("0x1337"))
218+
miner.Start()
217219
// Stop the downloader and wait for the update loop to run
218220
mux.Post(downloader.DoneEvent{})
219-
220221
waitForMiningState(t, miner, true)
221-
// The miner should now be using the good address
222-
if got, exp := miner.coinbase, common.HexToAddress("0x1337"); got != exp {
223-
t.Fatalf("Wrong coinbase, got %x expected %x", got, exp)
222+
223+
coinbase := common.HexToAddress("0xdeedbeef")
224+
miner.SetEtherbase(coinbase)
225+
if addr := miner.worker.etherbase(); addr != coinbase {
226+
t.Fatalf("Unexpected etherbase want %x got %x", coinbase, addr)
224227
}
225228
}
226229

miner/worker.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,14 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
276276
chainConfig: chainConfig,
277277
engine: engine,
278278
eth: eth,
279-
mux: mux,
280279
chain: eth.BlockChain(),
280+
mux: mux,
281281
isLocalBlock: isLocalBlock,
282282
localUncles: make(map[common.Hash]*types.Block),
283283
remoteUncles: make(map[common.Hash]*types.Block),
284284
unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), sealingLogAtDepth),
285+
coinbase: config.Etherbase,
286+
extra: config.ExtraData,
285287
pendingTasks: make(map[common.Hash]*task),
286288
txsCh: make(chan core.NewTxsEvent, txChanSize),
287289
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
@@ -290,8 +292,8 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
290292
getWorkCh: make(chan *getWorkReq),
291293
taskCh: make(chan *task),
292294
resultCh: make(chan *types.Block, resultQueueSize),
293-
exitCh: make(chan struct{}),
294295
startCh: make(chan struct{}, 1),
296+
exitCh: make(chan struct{}),
295297
resubmitIntervalCh: make(chan time.Duration),
296298
resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize),
297299
}
@@ -340,6 +342,13 @@ func (w *worker) setEtherbase(addr common.Address) {
340342
w.coinbase = addr
341343
}
342344

345+
// etherbase retrieves the configured etherbase address.
346+
func (w *worker) etherbase() common.Address {
347+
w.mu.RLock()
348+
defer w.mu.RUnlock()
349+
return w.coinbase
350+
}
351+
343352
func (w *worker) setGasCeil(ceil uint64) {
344353
w.mu.Lock()
345354
defer w.mu.Unlock()
@@ -1114,11 +1123,11 @@ func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) {
11141123
// Set the coinbase if the worker is running or it's required
11151124
var coinbase common.Address
11161125
if w.isRunning() {
1117-
if w.coinbase == (common.Address{}) {
1126+
coinbase = w.etherbase()
1127+
if coinbase == (common.Address{}) {
11181128
log.Error("Refusing to mine without etherbase")
11191129
return
11201130
}
1121-
coinbase = w.coinbase // Use the preset address as the fee recipient
11221131
}
11231132
work, err := w.prepareWork(&generateParams{
11241133
timestamp: uint64(timestamp),

0 commit comments

Comments
 (0)