Skip to content

Commit 19f4dd5

Browse files
committed
*: diff #499
1 parent 1117fbc commit 19f4dd5

File tree

28 files changed

+774
-631
lines changed

28 files changed

+774
-631
lines changed

Makefile

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# with Go source code. If you know what GOPATH is then you probably
33
# don't need to bother with make.
44

5-
.PHONY: geth android ios evm all test clean privnet_nodes_stop privnet_bootnode_stop privnet_stop privnet_clean privnet_start privnet_start_four privnet_start_seven
5+
.PHONY: geth all test lint fmt clean devtools help privnet_nodes_stop privnet_bootnode_stop privnet_stop privnet_clean privnet_start privnet_start_four privnet_start_seven
66

77
GETHBIN = ./build/bin
88
GO ?= latest
@@ -120,25 +120,29 @@ define init_node
120120
@$(GETHBIN)/geth init --datadir $(1)/$(2) $(1)/$(GENESIS_WORK_JSON) > $(1)/$(2)/geth_init.log 2>&1
121121
endef
122122

123-
#? geth: Build geth
123+
#? geth: Build geth.
124124
geth:
125125
$(GORUN) build/ci.go install ./cmd/geth
126126
@echo "Done building."
127127
@echo "Run \"$(GETHBIN)/geth\" to launch geth."
128128

129-
#? all: Build all packages and executables
129+
#? all: Build all packages and executables.
130130
all:
131131
$(GORUN) build/ci.go install
132132

133-
#? test: Run the tests
133+
#? test: Run the tests.
134134
test: all
135135
$(GORUN) build/ci.go test
136136

137-
#? lint: Run certain pre-selected linters
137+
#? lint: Run certain pre-selected linters.
138138
lint: ## Run linters.
139139
$(GORUN) build/ci.go lint
140140

141-
#? clean: Clean go cache, built executables, and the auto generated folder
141+
#? fmt: Ensure consistent code formatting.
142+
fmt:
143+
gofmt -s -w $(shell find . -name "*.go")
144+
145+
#? clean: Clean go cache, built executables, and the auto generated folder.
142146
clean:
143147
go clean -cache
144148
rm -fr build/_workspace/pkg/ $(GETHBIN)/*
@@ -155,8 +159,16 @@ devtools:
155159
@type "solc" 2> /dev/null || echo 'Please install solc'
156160
@type "protoc" 2> /dev/null || echo 'Please install protoc'
157161

158-
# Privnet targets
162+
#? help: Get more info on make commands.
163+
help: Makefile
164+
@echo ''
165+
@echo 'Usage:'
166+
@echo ' make [target]'
167+
@echo ''
168+
@echo 'Targets:'
169+
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'
159170

171+
# Privnet targets
160172
privnet_nodes_stop:
161173
@echo "Killing nodes processes"
162174
@killall -w -v -INT geth || :
@@ -347,9 +359,3 @@ docker_privnet_stop_seven:
347359

348360
docker_clean_node_img:
349361
docker rmi neox_node
350-
351-
#? help: Get more info on make commands.
352-
help: Makefile
353-
@echo " Choose a command run in go-ethereum:"
354-
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'
355-
.PHONY: help

accounts/manager.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ import (
2929
// the manager will buffer in its channel.
3030
const managerSubBufferSize = 50
3131

32-
// Config contains the settings of the global account manager.
33-
//
34-
// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management
35-
// is removed in favor of Clef.
32+
// Config is a legacy struct which is not used
3633
type Config struct {
3734
InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed
3835
}
@@ -47,7 +44,6 @@ type newBackendEvent struct {
4744
// Manager is an overarching account manager that can communicate with various
4845
// backends for signing transactions.
4946
type Manager struct {
50-
config *Config // Global account manager configurations
5147
backends map[reflect.Type][]Backend // Index of backends currently registered
5248
updaters []event.Subscription // Wallet update subscriptions for all backends
5349
updates chan WalletEvent // Subscription sink for backend wallet changes
@@ -78,7 +74,6 @@ func NewManager(config *Config, backends ...Backend) *Manager {
7874
}
7975
// Assemble the account manager and return
8076
am := &Manager{
81-
config: config,
8277
backends: make(map[reflect.Type][]Backend),
8378
updaters: subs,
8479
updates: updates,
@@ -106,11 +101,6 @@ func (am *Manager) Close() error {
106101
return <-errc
107102
}
108103

109-
// Config returns the configuration of account manager.
110-
func (am *Manager) Config() *Config {
111-
return am.config
112-
}
113-
114104
// AddBackend starts the tracking of an additional backend for wallet updates.
115105
// cmd/geth assumes once this func returns the backends have been already integrated.
116106
func (am *Manager) AddBackend(backend Backend) {

cmd/geth/accountcmd.go

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717
package main
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"os"
23+
"strings"
2224

2325
"github.com/ethereum/go-ethereum/accounts"
2426
"github.com/ethereum/go-ethereum/accounts/keystore"
2527
"github.com/ethereum/go-ethereum/cmd/utils"
28+
"github.com/ethereum/go-ethereum/common"
2629
"github.com/ethereum/go-ethereum/crypto"
2730
"github.com/ethereum/go-ethereum/log"
2831
"github.com/urfave/cli/v2"
@@ -275,6 +278,24 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
275278
return *match
276279
}
277280

281+
// readPasswordFromFile reads the first line of the given file, trims line endings,
282+
// and returns the password and whether the reading was successful.
283+
func readPasswordFromFile(path string) (string, bool) {
284+
if path == "" {
285+
return "", false
286+
}
287+
text, err := os.ReadFile(path)
288+
if err != nil {
289+
utils.Fatalf("Failed to read password file: %v", err)
290+
}
291+
lines := strings.Split(string(text), "\n")
292+
if len(lines) == 0 {
293+
return "", false
294+
}
295+
// Sanitise DOS line endings.
296+
return strings.TrimRight(lines[0], "\r"), true
297+
}
298+
278299
// accountCreate creates a new account into the keystore defined by the CLI flags.
279300
func accountCreate(ctx *cli.Context) error {
280301
cfg := loadBaseConfig(ctx)
@@ -292,8 +313,10 @@ func accountCreate(ctx *cli.Context) error {
292313
scryptP = keystore.LightScryptP
293314
}
294315

295-
password := utils.GetPassPhraseWithList("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
296-
316+
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
317+
if !ok {
318+
password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true)
319+
}
297320
account, err := keystore.StoreKey(keydir, password, scryptN, scryptP)
298321

299322
if err != nil {
@@ -323,10 +346,23 @@ func accountUpdate(ctx *cli.Context) error {
323346
ks := backends[0].(*keystore.KeyStore)
324347

325348
for _, addr := range ctx.Args().Slice() {
326-
account, oldPassword := unlockAccount(ks, addr, 0, nil)
327-
newPassword := utils.GetPassPhraseWithList("Please give a new password. Do not forget this password.", true, 0, nil)
328-
if err := ks.Update(account, oldPassword, newPassword); err != nil {
329-
utils.Fatalf("Could not update the account: %v", err)
349+
if !common.IsHexAddress(addr) {
350+
return errors.New("address must be specified in hexadecimal form")
351+
}
352+
account := accounts.Account{Address: common.HexToAddress(addr)}
353+
newPassword := utils.GetPassPhrase("Please give a NEW password. Do not forget this password.", true)
354+
updateFn := func(attempt int) error {
355+
prompt := fmt.Sprintf("Please provide the OLD password for account %s | Attempt %d/%d", addr, attempt+1, 3)
356+
password := utils.GetPassPhrase(prompt, false)
357+
return ks.Update(account, password, newPassword)
358+
}
359+
// let user attempt unlock thrice.
360+
err := updateFn(0)
361+
for attempts := 1; attempts < 3 && errors.Is(err, keystore.ErrDecrypt); attempts++ {
362+
err = updateFn(attempts)
363+
}
364+
if err != nil {
365+
return fmt.Errorf("could not update account: %w", err)
330366
}
331367
}
332368
return nil
@@ -347,10 +383,12 @@ func importWallet(ctx *cli.Context) error {
347383
if len(backends) == 0 {
348384
utils.Fatalf("Keystore is not available")
349385
}
386+
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
387+
if !ok {
388+
password = utils.GetPassPhrase("", false)
389+
}
350390
ks := backends[0].(*keystore.KeyStore)
351-
passphrase := utils.GetPassPhraseWithList("", false, 0, utils.MakePasswordList(ctx))
352-
353-
acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
391+
acct, err := ks.ImportPreSaleKey(keyJSON, password)
354392
if err != nil {
355393
utils.Fatalf("%v", err)
356394
}
@@ -373,9 +411,11 @@ func accountImport(ctx *cli.Context) error {
373411
utils.Fatalf("Keystore is not available")
374412
}
375413
ks := backends[0].(*keystore.KeyStore)
376-
passphrase := utils.GetPassPhraseWithList("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
377-
378-
acct, err := ks.ImportECDSA(key, passphrase)
414+
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
415+
if !ok {
416+
password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true)
417+
}
418+
acct, err := ks.ImportECDSA(key, password)
379419
if err != nil {
380420
utils.Fatalf("Could not create the account: %v", err)
381421
}

cmd/geth/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
234234

235235
if ctx.IsSet(utils.DeveloperFlag.Name) {
236236
// Start dev mode.
237-
simBeacon, err := catalyst.NewSimulatedBeacon(ctx.Uint64(utils.DeveloperPeriodFlag.Name), eth)
237+
simBeacon, err := catalyst.NewSimulatedBeacon(ctx.Uint64(utils.DeveloperPeriodFlag.Name), cfg.Eth.Miner.Etherbase, eth)
238238
if err != nil {
239239
utils.Fatalf("failed to register dev mode catalyst service: %v", err)
240240
}

consensus/beacon/consensus.go

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ func New(ethone consensus.Engine) *Beacon {
7272
return &Beacon{ethone: ethone}
7373
}
7474

75+
// isPostMerge reports whether the given block number is assumed to be post-merge.
76+
// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or
77+
// PoA chain for unit testing purposes.
78+
func isPostMerge(config *params.ChainConfig, blockNum uint64, timestamp uint64) bool {
79+
mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0
80+
return mergedAtGenesis ||
81+
config.MergeNetsplitBlock != nil && blockNum >= config.MergeNetsplitBlock.Uint64() ||
82+
config.ShanghaiTime != nil && timestamp >= *config.ShanghaiTime
83+
}
84+
7585
// Author implements consensus.Engine, returning the verified author of the block.
7686
func (beacon *Beacon) Author(header *types.Header) (common.Address, error) {
7787
if !beacon.IsPoSHeader(header) {
@@ -83,78 +93,63 @@ func (beacon *Beacon) Author(header *types.Header) (common.Address, error) {
8393
// VerifyHeader checks whether a header conforms to the consensus rules of the
8494
// stock Ethereum consensus engine.
8595
func (beacon *Beacon) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header) error {
86-
reached, err := IsTTDReached(chain, header.ParentHash, header.Number.Uint64()-1)
87-
if err != nil {
88-
return err
89-
}
90-
if !reached {
91-
return beacon.ethone.VerifyHeader(chain, header)
92-
}
93-
// Short circuit if the parent is not known
96+
// During the live merge transition, the consensus engine used the terminal
97+
// total difficulty to detect when PoW (PoA) switched to PoS. Maintaining the
98+
// total difficulty values however require applying all the blocks from the
99+
// genesis to build up the TD. This stops being a possibility if the tail of
100+
// the chain is pruned already during sync.
101+
//
102+
// One heuristic that can be used to distinguish pre-merge and post-merge
103+
// blocks is whether their *difficulty* is >0 or ==0 respectively. This of
104+
// course would mean that we cannot prove anymore for a past chain that it
105+
// truly transitioned at the correct TTD, but if we consider that ancient
106+
// point in time finalized a long time ago, there should be no attempt from
107+
// the consensus client to rewrite very old history.
108+
//
109+
// One thing that's probably not needed but which we can add to make this
110+
// verification even stricter is to enforce that the chain can switch from
111+
// >0 to ==0 TD only once by forbidding an ==0 to be followed by a >0.
112+
113+
// Verify that we're not reverting to pre-merge from post-merge
94114
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
95115
if parent == nil {
96116
return consensus.ErrUnknownAncestor
97117
}
98-
// Sanity checks passed, do a proper verification
99-
return beacon.verifyHeader(chain, header, parent)
100-
}
101-
102-
// errOut constructs an error channel with prefilled errors inside.
103-
func errOut(n int, err error) chan error {
104-
errs := make(chan error, n)
105-
for i := 0; i < n; i++ {
106-
errs <- err
118+
if parent.Difficulty.Sign() == 0 && header.Difficulty.Sign() > 0 {
119+
return consensus.ErrInvalidTerminalBlock
120+
}
121+
// Check >0 TDs with pre-merge, --0 TDs with post-merge rules
122+
if header.Difficulty.Sign() > 0 {
123+
return beacon.ethone.VerifyHeader(chain, header)
107124
}
108-
return errs
125+
return beacon.verifyHeader(chain, header, parent)
109126
}
110127

111128
// splitHeaders splits the provided header batch into two parts according to
112-
// the configured ttd. It requires the parent of header batch along with its
113-
// td are stored correctly in chain. If ttd is not configured yet, all headers
114-
// will be treated legacy PoW headers.
129+
// the difficulty field.
130+
//
115131
// Note, this function will not verify the header validity but just split them.
116-
func (beacon *Beacon) splitHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) ([]*types.Header, []*types.Header, error) {
117-
// TTD is not defined yet, all headers should be in legacy format.
118-
ttd := chain.Config().TerminalTotalDifficulty
119-
ptd := chain.GetTd(headers[0].ParentHash, headers[0].Number.Uint64()-1)
120-
if ptd == nil {
121-
return nil, nil, consensus.ErrUnknownAncestor
122-
}
123-
// The entire header batch already crosses the transition.
124-
if ptd.Cmp(ttd) >= 0 {
125-
return nil, headers, nil
126-
}
132+
func (beacon *Beacon) splitHeaders(headers []*types.Header) ([]*types.Header, []*types.Header) {
127133
var (
128134
preHeaders = headers
129135
postHeaders []*types.Header
130-
td = new(big.Int).Set(ptd)
131-
tdPassed bool
132136
)
133137
for i, header := range headers {
134-
if tdPassed {
138+
if header.Difficulty.Sign() == 0 {
135139
preHeaders = headers[:i]
136140
postHeaders = headers[i:]
137141
break
138142
}
139-
td = td.Add(td, header.Difficulty)
140-
if td.Cmp(ttd) >= 0 {
141-
// This is the last PoW header, it still belongs to
142-
// the preHeaders, so we cannot split+break yet.
143-
tdPassed = true
144-
}
145143
}
146-
return preHeaders, postHeaders, nil
144+
return preHeaders, postHeaders
147145
}
148146

149147
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
150148
// concurrently. The method returns a quit channel to abort the operations and
151149
// a results channel to retrieve the async verifications.
152150
// VerifyHeaders expect the headers to be ordered and continuous.
153151
func (beacon *Beacon) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header) (chan<- struct{}, <-chan error) {
154-
preHeaders, postHeaders, err := beacon.splitHeaders(chain, headers)
155-
if err != nil {
156-
return make(chan struct{}), errOut(len(headers), err)
157-
}
152+
preHeaders, postHeaders := beacon.splitHeaders(headers)
158153
if len(postHeaders) == 0 {
159154
return beacon.ethone.VerifyHeaders(chain, headers)
160155
}
@@ -449,8 +444,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash {
449444
// the difficulty that a new block should have when created at time
450445
// given the parent block's time and difficulty.
451446
func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
452-
// Transition isn't triggered yet, use the legacy rules for calculation
453-
if reached, _ := IsTTDReached(chain, parent.Hash(), parent.Number.Uint64()); !reached {
447+
if !isPostMerge(chain.Config(), parent.Number.Uint64()+1, time) {
454448
return beacon.ethone.CalcDifficulty(chain, time, parent)
455449
}
456450
return beaconDifficulty

0 commit comments

Comments
 (0)