From a9ab53d751b018ee493b909d520eb5f3daba6734 Mon Sep 17 00:00:00 2001 From: Sina M <1591639+s1na@users.noreply.github.com> Date: Fri, 3 Jan 2025 13:15:06 +0100 Subject: [PATCH 01/17] internal/ethapi: update default simulation timestamp increment to 12 (#30981) Update the default timestamp increment to 12s for `eth_simulate` endpoint --- internal/ethapi/simulate.go | 2 +- internal/ethapi/simulate_test.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 5bd0079a93..130eaa9724 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -45,7 +45,7 @@ const ( maxSimulateBlocks = 256 // timestampIncrement is the default increment between block timestamps. - timestampIncrement = 1 + timestampIncrement = 12 ) // simBlock is a batch of calls to be simulated sequentially. diff --git a/internal/ethapi/simulate_test.go b/internal/ethapi/simulate_test.go index 52ae40cad0..c747b76477 100644 --- a/internal/ethapi/simulate_test.go +++ b/internal/ethapi/simulate_test.go @@ -41,19 +41,19 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { baseNumber: 10, baseTimestamp: 50, blocks: []simBlock{{}, {}, {}}, - expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}}, + expected: []result{{number: 11, timestamp: 62}, {number: 12, timestamp: 74}, {number: 13, timestamp: 86}}, }, { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(70)}}, {}}, - expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 70}, {number: 14, timestamp: 71}}, + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(80)}}, {}}, + expected: []result{{number: 11, timestamp: 62}, {number: 12, timestamp: 74}, {number: 13, timestamp: 80}, {number: 14, timestamp: 92}}, }, { baseNumber: 10, baseTimestamp: 50, blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(14)}}, {}}, - expected: []result{{number: 11, timestamp: 51}, {number: 12, timestamp: 52}, {number: 13, timestamp: 53}, {number: 14, timestamp: 54}, {number: 15, timestamp: 55}}, + expected: []result{{number: 11, timestamp: 62}, {number: 12, timestamp: 74}, {number: 13, timestamp: 86}, {number: 14, timestamp: 98}, {number: 15, timestamp: 110}}, }, { baseNumber: 10, @@ -64,8 +64,8 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(52)}}}, - err: "block timestamps must be in order: 52 <= 52", + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(74)}}}, + err: "block timestamps must be in order: 74 <= 74", }, { baseNumber: 10, @@ -76,8 +76,8 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) { { baseNumber: 10, baseTimestamp: 50, - blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(61)}}}, - err: "block timestamps must be in order: 61 <= 61", + blocks: []simBlock{{BlockOverrides: &override.BlockOverrides{Number: newInt(11), Time: newUint64(60)}}, {BlockOverrides: &override.BlockOverrides{Number: newInt(13), Time: newUint64(72)}}}, + err: "block timestamps must be in order: 72 <= 72", }, } { sim := &simulator{base: &types.Header{Number: big.NewInt(int64(tc.baseNumber)), Time: tc.baseTimestamp}} From c5a8d3485191d15363b9817da1afcac3fce5ddeb Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 6 Jan 2025 07:52:01 +0100 Subject: [PATCH 02/17] core/rawdb: fix panic in freezer (#30973) Fixes an issue where the node panics when an LStat fails with something other than os.ErrNotExist closes https://github.com/ethereum/go-ethereum/issues/30968 --- core/rawdb/freezer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index d6370cee33..c5a72eff7e 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -87,6 +87,10 @@ func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize ui ) // Ensure the datadir is not a symbolic link if it exists. if info, err := os.Lstat(datadir); !os.IsNotExist(err) { + if info == nil { + log.Warn("Could not Lstat the database", "path", datadir) + return nil, errors.New("lstat failed") + } if info.Mode()&os.ModeSymlink != 0 { log.Warn("Symbolic link ancient database is not supported", "path", datadir) return nil, errSymlinkDatadir From 6897a4a9e0c825c01b63971ee1fe6b9fbc2b4cd3 Mon Sep 17 00:00:00 2001 From: georgehao Date: Mon, 6 Jan 2025 23:28:28 +0800 Subject: [PATCH 03/17] core/types: improve printList in DeriveSha test (#30969) --- core/types/hashing_test.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/core/types/hashing_test.go b/core/types/hashing_test.go index a6949414f3..c846ecd0c5 100644 --- a/core/types/hashing_test.go +++ b/core/types/hashing_test.go @@ -111,7 +111,7 @@ func TestFuzzDeriveSha(t *testing.T) { exp := types.DeriveSha(newDummy(i), trie.NewEmpty(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil))) got := types.DeriveSha(newDummy(i), trie.NewStackTrie(nil)) if !bytes.Equal(got[:], exp[:]) { - printList(newDummy(seed)) + printList(t, newDummy(seed)) t.Fatalf("seed %d: got %x exp %x", seed, got, exp) } } @@ -192,15 +192,21 @@ func (d *dummyDerivableList) EncodeIndex(i int, w *bytes.Buffer) { io.CopyN(w, mrand.New(src), size) } -func printList(l types.DerivableList) { - fmt.Printf("list length: %d\n", l.Len()) - fmt.Printf("{\n") +func printList(t *testing.T, l types.DerivableList) { + var buf bytes.Buffer + _, _ = fmt.Fprintf(&buf, "list length: %d, ", l.Len()) + buf.WriteString("list: [") for i := 0; i < l.Len(); i++ { - var buf bytes.Buffer - l.EncodeIndex(i, &buf) - fmt.Printf("\"%#x\",\n", buf.Bytes()) + var itemBuf bytes.Buffer + l.EncodeIndex(i, &itemBuf) + if i == l.Len()-1 { + _, _ = fmt.Fprintf(&buf, "\"%#x\"", itemBuf.Bytes()) + } else { + _, _ = fmt.Fprintf(&buf, "\"%#x\",", itemBuf.Bytes()) + } } - fmt.Printf("},\n") + buf.WriteString("]") + t.Log(buf.String()) } type flatList []string From 92980746339dcaf397a0367dca0ddf3d27664d28 Mon Sep 17 00:00:00 2001 From: Martin HS Date: Mon, 6 Jan 2025 16:31:53 +0100 Subject: [PATCH 04/17] eth/protocols/eth: prevent hanging dispatch (#30918) This PR attempts to fix a strange test-failure (timeout) observed on a windows-32 platform. https://ci.appveyor.com/project/ethereum/go-ethereum/builds/51174391/job/d8ascanwwltrlqd5 A goroutine is stuck trying to deliver a response: ``` goroutine 9632 [select, 29 minutes]: github.com/ethereum/go-ethereum/eth/protocols/eth.(*Peer).dispatchResponse(0x314f100, 0x3e5f6d0, 0x3acbb84) C:/projects/go-ethereum/eth/protocols/eth/dispatcher.go:172 +0x2a5 github.com/ethereum/go-ethereum/eth/protocols/eth.handleBlockHeaders({0x12abe68, 0x30021b8}, {0x12a815c, 0x40b41c0}, 0x314f100) C:/projects/go-ethereum/eth/protocols/eth/handlers.go:301 +0x173 github.com/ethereum/go-ethereum/eth/protocols/eth.handleMessage({0x12abe68, 0x30021b8}, 0x314f100) C:/projects/go-ethereum/eth/protocols/eth/handler.go:205 +0x4f6 github.com/ethereum/go-ethereum/eth/protocols/eth.Handle({0x12abe68, 0x30021b8}, 0x314f100) C:/projects/go-ethereum/eth/protocols/eth/handler.go:149 +0x33 github.com/ethereum/go-ethereum/eth.testSnapSyncDisabling.func1(0x314f100) C:/projects/go-ethereum/eth/sync_test.go:65 +0x33 github.com/ethereum/go-ethereum/eth.(*handler).runEthPeer(0x30021b8, 0x314f100, 0x427f648) C:/projects/go-ethereum/eth/handler.go:355 +0xe65 created by github.com/ethereum/go-ethereum/eth.testSnapSyncDisabling in goroutine 11 C:/projects/go-ethereum/eth/sync_test.go:64 +0x54f FAIL github.com/ethereum/go-ethereum/eth 1800.138s ``` --------- Co-authored-by: Gary Rong --- eth/protocols/eth/dispatcher.go | 2 ++ eth/sync_test.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/eth/protocols/eth/dispatcher.go b/eth/protocols/eth/dispatcher.go index 146eec3f60..cba40596fc 100644 --- a/eth/protocols/eth/dispatcher.go +++ b/eth/protocols/eth/dispatcher.go @@ -174,6 +174,8 @@ func (p *Peer) dispatchResponse(res *Response, metadata func() interface{}) erro return <-res.Done // Response delivered, return any errors case <-res.Req.cancel: return nil // Request cancelled, silently discard response + case <-p.term: + return errDisconnected } } diff --git a/eth/sync_test.go b/eth/sync_test.go index 57eea73790..cad3a4732e 100644 --- a/eth/sync_test.go +++ b/eth/sync_test.go @@ -88,7 +88,7 @@ func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) { if err := empty.handler.downloader.BeaconSync(ethconfig.SnapSync, full.chain.CurrentBlock(), nil); err != nil { t.Fatal("sync failed:", err) } - empty.handler.enableSyncedFeatures() + time.Sleep(time.Second * 5) // Downloader internally has to wait a timer (3s) to be expired before exiting if empty.handler.snapSync.Load() { t.Fatalf("snap sync not disabled after successful synchronisation") From e75f354ae7c29d70f100477afa3600cbeff9f5b4 Mon Sep 17 00:00:00 2001 From: Savely <136869149+savvar9991@users.noreply.github.com> Date: Tue, 7 Jan 2025 20:31:10 +1100 Subject: [PATCH 05/17] cmd/clef: fix JS issues in documentation (#30980) Fixes a couple of js-flaws in the docs --- cmd/clef/rules.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/clef/rules.md b/cmd/clef/rules.md index cc4a645596..3cd1bb52c6 100644 --- a/cmd/clef/rules.md +++ b/cmd/clef/rules.md @@ -7,7 +7,7 @@ It enables usecases like the following: * I want to auto-approve transactions with contract `CasinoDapp`, with up to `0.05 ether` in value to maximum `1 ether` per 24h period * I want to auto-approve transaction to contract `EthAlarmClock` with `data`=`0xdeadbeef`, if `value=0`, `gas < 44k` and `gasPrice < 40Gwei` -The two main features that are required for this to work well are; +The two main features that are required for this to work well are: 1. Rule Implementation: how to create, manage, and interpret rules in a flexible but secure manner 2. Credential management and credentials; how to provide auto-unlock without exposing keys unnecessarily. @@ -29,10 +29,10 @@ function asBig(str) { // Approve transactions to a certain contract if the value is below a certain limit function ApproveTx(req) { - var limit = big.Newint("0xb1a2bc2ec50000") + var limit = new BigNumber("0xb1a2bc2ec50000") var value = asBig(req.transaction.value); - if (req.transaction.to.toLowerCase() == "0xae967917c465db8578ca9024c205720b1a3651a9") && value.lt(limit)) { + if (req.transaction.to.toLowerCase() == "0xae967917c465db8578ca9024c205720b1a3651a9" && value.lt(limit)) { return "Approve" } // If we return "Reject", it will be rejected. From 5065e6c9356276e8fa877536ab82f25fb9fa5c86 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 7 Jan 2025 13:49:13 +0300 Subject: [PATCH 06/17] triedb/pathdb: fix tester generator (#30972) This change fixes is a rare bug in test generator: If the run is very unlucky it can use `modifyAccountOp` / `deleteAccountOp` without creating any account, leading to have a trie root same as the parent. This change makes the first operation always be a creation. --- triedb/pathdb/database_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 648230df15..3b35370c84 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -222,7 +222,12 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode dirties = make(map[common.Hash]struct{}) ) for i := 0; i < 20; i++ { - switch rand.Intn(opLen) { + // Start with account creation always + op := createAccountOp + if i > 0 { + op = rand.Intn(opLen) + } + switch op { case createAccountOp: // account creation addr := testrand.Address() From 033de2a05bdbea87b4efc5156511afe42c38fd55 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 8 Jan 2025 14:22:37 +0100 Subject: [PATCH 07/17] README: remove private network section from readme (#31005) --- README.md | 125 ++++-------------------------------------------------- 1 file changed, 9 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 27842008aa..45b80e86a6 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,14 @@ on how you can run your own `geth` instance. Minimum: -* CPU with 2+ cores -* 4GB RAM +* CPU with 4+ cores +* 8GB RAM * 1TB free storage space to sync the Mainnet * 8 MBit/sec download Internet service Recommended: -* Fast CPU with 4+ cores +* Fast CPU with 8+ cores * 16GB+ RAM * High-performance SSD with at least 1TB of free space * 25+ MBit/sec download Internet service @@ -138,8 +138,6 @@ export your existing configuration: $ geth --your-favourite-flags dumpconfig ``` -*Note: This works only with `geth` v1.6.0 and above.* - #### Docker quick start One of the quickest ways to get Ethereum up and running on your machine is by using @@ -187,7 +185,6 @@ HTTP based JSON-RPC API options: * `--ws.api` API's offered over the WS-RPC interface (default: `eth,net,web3`) * `--ws.origins` Origins from which to accept WebSocket requests * `--ipcdisable` Disable the IPC-RPC server - * `--ipcapi` API's offered over the IPC-RPC interface (default: `admin,debug,eth,miner,net,personal,txpool,web3`) * `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it) You'll need to use your own programming environments' capabilities (libraries, tools, etc) to @@ -206,118 +203,14 @@ APIs!** Maintaining your own private network is more involved as a lot of configurations taken for granted in the official networks need to be manually set up. -#### Defining the private genesis state +Unfortunately since [the Merge](https://ethereum.org/en/roadmap/merge/) it is no longer possible +to easily set up a network of geth nodes without also setting up a corresponding beacon chain. -First, you'll need to create the genesis state of your networks, which all nodes need to be -aware of and agree upon. This consists of a small JSON file (e.g. call it `genesis.json`): +There are three different solutions depending on your use case: -```json -{ - "config": { - "chainId": , - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0 - }, - "alloc": {}, - "coinbase": "0x0000000000000000000000000000000000000000", - "difficulty": "0x20000", - "extraData": "", - "gasLimit": "0x2fefd8", - "nonce": "0x0000000000000042", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x00" -} -``` - -The above fields should be fine for most purposes, although we'd recommend changing -the `nonce` to some random value so you prevent unknown remote nodes from being able -to connect to you. If you'd like to pre-fund some accounts for easier testing, create -the accounts and populate the `alloc` field with their addresses. - -```json -"alloc": { - "0x0000000000000000000000000000000000000001": { - "balance": "111111111" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "222222222" - } -} -``` - -With the genesis state defined in the above JSON file, you'll need to initialize **every** -`geth` node with it prior to starting it up to ensure all blockchain parameters are correctly -set: - -```shell -$ geth init path/to/genesis.json -``` - -#### Creating the rendezvous point - -With all nodes that you want to run initialized to the desired genesis state, you'll need to -start a bootstrap node that others can use to find each other in your network and/or over -the internet. The clean way is to configure and run a dedicated bootnode: - -```shell -# Use the devp2p tool to create a node file. -# The devp2p tool is also part of the 'alltools' distribution bundle. -$ devp2p key generate node1.key -# file node1.key is created. -$ devp2p key to-enr -ip 10.2.3.4 -udp 30303 -tcp 30303 node1.key -# Prints the ENR for use in --bootnode flag of other nodes. -# Note this method requires knowing the IP/ports ahead of time. -$ geth --nodekey=node1.key -``` - -With the bootnode online, it will display an [`enode` URL](https://ethereum.org/en/developers/docs/networking-layer/network-addresses/#enode) -that other nodes can use to connect to it and exchange peer information. Make sure to -replace the displayed IP address information (most probably `[::]`) with your externally -accessible IP to get the actual `enode` URL. - -*Note: You could previously use the `bootnode` utility to start a stripped down version of geth. This is not possible anymore.* - -#### Starting up your member nodes - -With the bootnode operational and externally reachable (you can try -`telnet ` to ensure it's indeed reachable), start every subsequent `geth` -node pointed to the bootnode for peer discovery via the `--bootnodes` flag. It will -probably also be desirable to keep the data directory of your private network separated, so -do also specify a custom `--datadir` flag. - -```shell -$ geth --datadir=path/to/custom/data/folder --bootnodes= -``` - -*Note: Since your network will be completely cut off from the main and test networks, you'll -also need to configure a miner to process transactions and create new blocks for you.* - -#### Running a private miner - - -In a private network setting a single CPU miner instance is more than enough for -practical purposes as it can produce a stable stream of blocks at the correct intervals -without needing heavy resources (consider running on a single thread, no need for multiple -ones either). To start a `geth` instance for mining, run it with all your usual flags, extended -by: - -```shell -$ geth --mine --miner.threads=1 --miner.etherbase=0x0000000000000000000000000000000000000000 -``` - -Which will start mining blocks and transactions on a single CPU thread, crediting all -proceedings to the account specified by `--miner.etherbase`. You can further tune the mining -by changing the default gas limit blocks converge to (`--miner.targetgaslimit`) and the price -transactions are accepted at (`--miner.gasprice`). + * If you are looking for a simple way to test smart contracts from go in your CI, you can use the [Simulated Backend](https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings#blockchain-simulator). + * If you want a convenient single node environment for testing, you can use our [Dev Mode](https://geth.ethereum.org/docs/developers/dapp-developer/dev-mode). + * If you are looking for a multiple node test network, you can set one up quite easily with [Kurtosis](https://geth.ethereum.org/docs/fundamentals/kurtosis). ## Contribution From 82e963e5c981e36dc4b607dd0685c64cf4aabea8 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Fri, 10 Jan 2025 20:51:19 +0800 Subject: [PATCH 08/17] triedb/pathdb: configure different node hasher in pathdb (#31008) As the node hash scheme in verkle and merkle are totally different, the original default node hasher in pathdb is no longer suitable. Therefore, this pull request configures different node hasher respectively. --- core/genesis.go | 12 ++++- core/state/stateupdate.go | 5 +- core/types/hashes.go | 11 ---- internal/ethapi/override/override_test.go | 3 +- trie/trie_reader.go | 4 -- triedb/pathdb/database.go | 62 +++++++++++++++++------ triedb/pathdb/database_test.go | 4 +- triedb/pathdb/journal.go | 15 +++--- triedb/pathdb/layertree.go | 5 +- 9 files changed, 71 insertions(+), 50 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index 85ef049ba6..347789cf0c 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -127,8 +127,12 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { } // Create an ephemeral in-memory database for computing hash, // all the derived states will be discarded to not pollute disk. + emptyRoot := types.EmptyRootHash + if isVerkle { + emptyRoot = types.EmptyVerkleHash + } db := rawdb.NewMemoryDatabase() - statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb.NewDatabase(db, config), nil)) + statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil)) if err != nil { return common.Hash{}, err } @@ -148,7 +152,11 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { // flushAlloc is very similar with hash, but the main difference is all the // generated states will be persisted into the given database. func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) { - statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb, nil)) + emptyRoot := types.EmptyRootHash + if triedb.IsVerkle() { + emptyRoot = types.EmptyVerkleHash + } + statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil)) if err != nil { return common.Hash{}, err } diff --git a/core/state/stateupdate.go b/core/state/stateupdate.go index a320b72f11..45de660ca5 100644 --- a/core/state/stateupdate.go +++ b/core/state/stateupdate.go @@ -20,7 +20,6 @@ import ( "maps" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/triedb" ) @@ -133,8 +132,8 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common } } return &stateUpdate{ - originRoot: types.TrieRootHash(originRoot), - root: types.TrieRootHash(root), + originRoot: originRoot, + root: root, accounts: accounts, accountsOrigin: accountsOrigin, storages: storages, diff --git a/core/types/hashes.go b/core/types/hashes.go index 55506d63d0..05cfaeed74 100644 --- a/core/types/hashes.go +++ b/core/types/hashes.go @@ -19,7 +19,6 @@ package types import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" ) var ( @@ -47,13 +46,3 @@ var ( // EmptyVerkleHash is the known hash of an empty verkle trie. EmptyVerkleHash = common.Hash{} ) - -// TrieRootHash returns the hash itself if it's non-empty or the predefined -// emptyHash one instead. -func TrieRootHash(hash common.Hash) common.Hash { - if hash == (common.Hash{}) { - log.Error("Zero trie root hash!") - return EmptyRootHash - } - return hash -} diff --git a/internal/ethapi/override/override_test.go b/internal/ethapi/override/override_test.go index 07ed6442b2..02a17c1331 100644 --- a/internal/ethapi/override/override_test.go +++ b/internal/ethapi/override/override_test.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/triedb" ) @@ -36,7 +37,7 @@ func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil func TestStateOverrideMovePrecompile(t *testing.T) { db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) - statedb, err := state.New(common.Hash{}, db) + statedb, err := state.New(types.EmptyRootHash, db) if err != nil { t.Fatalf("failed to create statedb: %v", err) } diff --git a/trie/trie_reader.go b/trie/trie_reader.go index 4b8ba808df..a42cdb0cf9 100644 --- a/trie/trie_reader.go +++ b/trie/trie_reader.go @@ -19,7 +19,6 @@ package trie import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/triedb/database" ) @@ -34,9 +33,6 @@ type trieReader struct { // newTrieReader initializes the trie reader with the given node reader. func newTrieReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*trieReader, error) { if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash { - if stateRoot == (common.Hash{}) { - log.Error("Zero state root hash!") - } return &trieReader{owner: owner}, nil } reader, err := db.NodeReader(stateRoot) diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index 914b17de5b..c31f1d44f4 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-verkle" ) const ( @@ -148,6 +149,29 @@ var Defaults = &Config{ // ReadOnly is the config in order to open database in read only mode. var ReadOnly = &Config{ReadOnly: true} +// nodeHasher is the function to compute the hash of supplied node blob. +type nodeHasher func([]byte) (common.Hash, error) + +// merkleNodeHasher computes the hash of the given merkle node. +func merkleNodeHasher(blob []byte) (common.Hash, error) { + if len(blob) == 0 { + return types.EmptyRootHash, nil + } + return crypto.Keccak256Hash(blob), nil +} + +// verkleNodeHasher computes the hash of the given verkle node. +func verkleNodeHasher(blob []byte) (common.Hash, error) { + if len(blob) == 0 { + return types.EmptyVerkleHash, nil + } + n, err := verkle.ParseNode(blob, 0) + if err != nil { + return common.Hash{}, err + } + return n.Commit().Bytes(), nil +} + // Database is a multiple-layered structure for maintaining in-memory states // along with its dirty trie nodes. It consists of one persistent base layer // backed by a key-value store, on top of which arbitrarily many in-memory diff @@ -164,9 +188,10 @@ type Database struct { // readOnly is the flag whether the mutation is allowed to be applied. // It will be set automatically when the database is journaled during // the shutdown to reject all following unexpected mutations. - readOnly bool // Flag if database is opened in read only mode - waitSync bool // Flag if database is deactivated due to initial state sync - isVerkle bool // Flag if database is used for verkle tree + readOnly bool // Flag if database is opened in read only mode + waitSync bool // Flag if database is deactivated due to initial state sync + isVerkle bool // Flag if database is used for verkle tree + hasher nodeHasher // Trie node hasher config *Config // Configuration for database diskdb ethdb.Database // Persistent storage for matured trie nodes @@ -184,19 +209,21 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { } config = config.sanitize() + db := &Database{ + readOnly: config.ReadOnly, + isVerkle: isVerkle, + config: config, + diskdb: diskdb, + hasher: merkleNodeHasher, + } // Establish a dedicated database namespace tailored for verkle-specific // data, ensuring the isolation of both verkle and merkle tree data. It's // important to note that the introduction of a prefix won't lead to // substantial storage overhead, as the underlying database will efficiently // compress the shared key prefix. if isVerkle { - diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix)) - } - db := &Database{ - readOnly: config.ReadOnly, - isVerkle: isVerkle, - config: config, - diskdb: diskdb, + db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix)) + db.hasher = verkleNodeHasher } // Construct the layer tree by resolving the in-disk singleton state // and in-memory layer journal. @@ -277,6 +304,8 @@ func (db *Database) repairHistory() error { // // The passed in maps(nodes, states) will be retained to avoid copying everything. // Therefore, these maps must not be changed afterwards. +// +// The supplied parentRoot and root must be a valid trie hash value. func (db *Database) Update(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *StateSetWithOrigin) error { // Hold the lock to prevent concurrent mutations. db.lock.Lock() @@ -350,10 +379,9 @@ func (db *Database) Enable(root common.Hash) error { return errDatabaseReadOnly } // Ensure the provided state root matches the stored one. - root = types.TrieRootHash(root) - stored := types.EmptyRootHash - if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { - stored = crypto.Keccak256Hash(blob) + stored, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil)) + if err != nil { + return err } if stored != root { return fmt.Errorf("state root mismatch: stored %x, synced %x", stored, root) @@ -389,6 +417,8 @@ func (db *Database) Enable(root common.Hash) error { // Recover rollbacks the database to a specified historical point. // The state is supported as the rollback destination only if it's // canonical state and the corresponding trie histories are existent. +// +// The supplied root must be a valid trie hash value. func (db *Database) Recover(root common.Hash) error { db.lock.Lock() defer db.lock.Unlock() @@ -401,7 +431,6 @@ func (db *Database) Recover(root common.Hash) error { return errors.New("state rollback is non-supported") } // Short circuit if the target state is not recoverable - root = types.TrieRootHash(root) if !db.Recoverable(root) { return errStateUnrecoverable } @@ -434,9 +463,10 @@ func (db *Database) Recover(root common.Hash) error { } // Recoverable returns the indicator if the specified state is recoverable. +// +// The supplied root must be a valid trie hash value. func (db *Database) Recoverable(root common.Hash) bool { // Ensure the requested state is a known state. - root = types.TrieRootHash(root) id := rawdb.ReadStateID(db.diskdb, root) if id == nil { return false diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 3b35370c84..a6b1d3c045 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -458,8 +458,8 @@ func TestDatabaseRecoverable(t *testing.T) { // Initial state should be recoverable {types.EmptyRootHash, true}, - // Initial state should be recoverable - {common.Hash{}, true}, + // common.Hash{} is not a valid state root for revert + {common.Hash{}, false}, // Layers below current disk layer are recoverable {tester.roots[index-1], true}, diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 779a262fdd..267d675bc2 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -26,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" ) @@ -93,9 +92,9 @@ func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) { // loadLayers loads a pre-existing state layer backed by a key-value store. func (db *Database) loadLayers() layer { // Retrieve the root node of persistent state. - var root = types.EmptyRootHash - if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { - root = crypto.Keccak256Hash(blob) + root, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil)) + if err != nil { + log.Crit("Failed to compute node hash", "err", err) } // Load the layers by resolving the journal head, err := db.loadJournal(root) @@ -236,6 +235,8 @@ func (dl *diffLayer) journal(w io.Writer) error { // This is meant to be used during shutdown to persist the layer without // flattening everything down (bad for reorgs). And this function will mark the // database as read-only to prevent all following mutation to disk. +// +// The supplied root must be a valid trie hash value. func (db *Database) Journal(root common.Hash) error { // Retrieve the head layer to journal from. l := db.tree.get(root) @@ -265,9 +266,9 @@ func (db *Database) Journal(root common.Hash) error { } // Secondly write out the state root in disk, ensure all layers // on top are continuous with disk. - diskRoot := types.EmptyRootHash - if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 { - diskRoot = crypto.Keccak256Hash(blob) + diskRoot, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil)) + if err != nil { + return err } if err := rlp.Encode(journal, diskRoot); err != nil { return err diff --git a/triedb/pathdb/layertree.go b/triedb/pathdb/layertree.go index cf6b14e744..0bd086c2f3 100644 --- a/triedb/pathdb/layertree.go +++ b/triedb/pathdb/layertree.go @@ -22,7 +22,6 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie/trienode" ) @@ -62,7 +61,7 @@ func (tree *layerTree) get(root common.Hash) layer { tree.lock.RLock() defer tree.lock.RUnlock() - return tree.layers[types.TrieRootHash(root)] + return tree.layers[root] } // forEach iterates the stored layers inside and applies the @@ -92,7 +91,6 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6 // // Although we could silently ignore this internally, it should be the caller's // responsibility to avoid even attempting to insert such a layer. - root, parentRoot = types.TrieRootHash(root), types.TrieRootHash(parentRoot) if root == parentRoot { return errors.New("layer cycle") } @@ -112,7 +110,6 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6 // are crossed. All diffs beyond the permitted number are flattened downwards. func (tree *layerTree) cap(root common.Hash, layers int) error { // Retrieve the head layer to cap from - root = types.TrieRootHash(root) l := tree.get(root) if l == nil { return fmt.Errorf("triedb layer [%#x] missing", root) From c0882429f032da58620bcaa610007939aa7e0adb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 13 Jan 2025 15:26:10 +0800 Subject: [PATCH 09/17] build: upgrade golangci-lint to v1.63.4 (#31019) This PR upgrades `golangci-lint` to v1.63.4 and fixes a warn message which is reported by v1.63.4: ```text WARN [config_reader] The configuration option `run.skip-dirs-use-default` is deprecated, please use `issues.exclude-dirs-use-default`. ``` Also fixes 2 warnings which are reported by v1.63.4: ```text core/txpool/blobpool/blobpool.go:1754:12: S1005: unnecessary assignment to the blank identifier (gosimple) for acct, _ := range p.index { ^ core/txpool/legacypool/legacypool.go:1989:19: S1005: unnecessary assignment to the blank identifier (gosimple) for localSender, _ := range pool.locals.accounts { ^ ``` --- .golangci.yml | 6 +-- build/checksums.txt | 60 ++++++++++++++-------------- core/txpool/blobpool/blobpool.go | 2 +- core/txpool/legacypool/legacypool.go | 2 +- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index e355e6f9d1..b63251055b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,9 +3,6 @@ run: timeout: 20m tests: true - # default is true. Enables skipping of directories: - # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ - skip-dirs-use-default: true linters: disable-all: true @@ -54,6 +51,9 @@ linters-settings: exclude: [""] issues: + # default is true. Enables skipping of directories: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + exclude-dirs-use-default: true exclude-files: - core/genesis_alloc.go exclude-rules: diff --git a/build/checksums.txt b/build/checksums.txt index b8061c9244..b0b7a73a3b 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -56,37 +56,37 @@ fc77c0531406d092c5356167e45c05a22d16bea84e3fa555e0f03af085c11763 go1.23.4.windo 8347c1aa4e1e67954d12830f88dbe44bd7ac0ec134bb472783dbfb5a3a8865d0 go1.23.4.windows-arm64.msi db69cae5006753c785345c3215ad941f8b6224e2f81fec471c42d6857bee0e6f go1.23.4.windows-arm64.zip -# version:golangci 1.61.0 +# version:golangci 1.63.4 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v1.61.0/ -5c280ef3284f80c54fd90d73dc39ca276953949da1db03eb9dd0fbf868cc6e55 golangci-lint-1.61.0-darwin-amd64.tar.gz -544334890701e4e04a6e574bc010bea8945205c08c44cced73745a6378012d36 golangci-lint-1.61.0-darwin-arm64.tar.gz -e885a6f561092055930ebd298914d80e8fd2e10d2b1e9942836c2c6a115301fa golangci-lint-1.61.0-freebsd-386.tar.gz -b13f6a3f11f65e7ff66b734d7554df3bbae0f485768848424e7554ed289e19c2 golangci-lint-1.61.0-freebsd-amd64.tar.gz -cd8e7bbe5b8f33ed1597aa1cc588da96a3b9f22e1b9ae60d93511eae1a0ee8c5 golangci-lint-1.61.0-freebsd-armv6.tar.gz -7ade524dbd88bd250968f45e190af90e151fa5ee63dd6aa7f7bb90e8155db61d golangci-lint-1.61.0-freebsd-armv7.tar.gz -0fe3cd8a1ed8d9f54f48670a5af3df056d6040d94017057f0f4d65c930660ad9 golangci-lint-1.61.0-illumos-amd64.tar.gz -b463fc5053a612abd26393ebaff1d85d7d56058946f4f0f7bf25ed44ea899415 golangci-lint-1.61.0-linux-386.tar.gz -77cb0af99379d9a21d5dc8c38364d060e864a01bd2f3e30b5e8cc550c3a54111 golangci-lint-1.61.0-linux-amd64.tar.gz -af60ac05566d9351615cb31b4cc070185c25bf8cbd9b09c1873aa5ec6f3cc17e golangci-lint-1.61.0-linux-arm64.tar.gz -1f307f2fcc5d7d674062a967a0d83a7091e300529aa237ec6ad2b3dd14c897f5 golangci-lint-1.61.0-linux-armv6.tar.gz -3ad8cbaae75a547450844811300f99c4cd290277398e43d22b9eb1792d15af4c golangci-lint-1.61.0-linux-armv7.tar.gz -9be2ca67d961d7699079739cf6f7c8291c5183d57e34d1677de21ca19d0bd3ed golangci-lint-1.61.0-linux-loong64.tar.gz -90d005e1648115ebf0861b408eab9c936079a24763e883058b0a227cd3135d31 golangci-lint-1.61.0-linux-mips64.tar.gz -6d2ed4f49407115460b8c10ccfc40fd177e0887a48864a2879dd16e84ba2a48c golangci-lint-1.61.0-linux-mips64le.tar.gz -633089589af5a58b7430afb6eee107d4e9c99e8d91711ddc219eb13a07e8d3b8 golangci-lint-1.61.0-linux-ppc64le.tar.gz -4c1a097d9e0d1b4a8144dae6a1f5583a38d662f3bdc1498c4e954b6ed856be98 golangci-lint-1.61.0-linux-riscv64.tar.gz -30581d3c987d287b7064617f1a2694143e10dffc40bc25be6636006ee82d7e1c golangci-lint-1.61.0-linux-s390x.tar.gz -42530bf8100bd43c07f5efe6d92148ba6c5a7a712d510c6f24be85af6571d5eb golangci-lint-1.61.0-netbsd-386.tar.gz -b8bb07c920f6601edf718d5e82ec0784fd590b0992b42b6ec18da99f26013ed4 golangci-lint-1.61.0-netbsd-amd64.tar.gz -353a51527c60bd0776b0891b03f247c791986f625fca689d121972c624e54198 golangci-lint-1.61.0-netbsd-arm64.tar.gz -957a6272c3137910514225704c5dac0723b9c65eb7d9587366a997736e2d7580 golangci-lint-1.61.0-netbsd-armv6.tar.gz -a89eb28ff7f18f5cd52b914739360fa95cf2f643de4adeca46e26bec3a07e8d8 golangci-lint-1.61.0-netbsd-armv7.tar.gz -d8d74c43600b271393000717a4ed157d7a15bb85bab7db2efad9b63a694d4634 golangci-lint-1.61.0-windows-386.zip -e7bc2a81929a50f830244d6d2e657cce4f19a59aff49fa9000176ff34fda64ce golangci-lint-1.61.0-windows-amd64.zip -ed97c221596dd771e3dd9344872c140340bee2e819cd7a90afa1de752f1f2e0f golangci-lint-1.61.0-windows-arm64.zip -4b365233948b13d02d45928a5c390045e00945e919747b9887b5f260247541ae golangci-lint-1.61.0-windows-armv6.zip -595538fb64d152173959d28f6235227f9cd969a828e5af0c4e960d02af4ffd0e golangci-lint-1.61.0-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v1.63.4/ +878d017cc360e4fb19510d39852c8189852e3c48e7ce0337577df73507c97d68 golangci-lint-1.63.4-darwin-amd64.tar.gz +a2b630c2ac8466393f0ccbbede4462387b6c190697a70bc2298c6d2123f21bbf golangci-lint-1.63.4-darwin-arm64.tar.gz +8938b74aa92888e561a1c5a4c175110b92f84e7d24733703e6d9ebc39e9cd5f8 golangci-lint-1.63.4-freebsd-386.tar.gz +054903339d620df2e760b978920100986e3b03bcb058f669d520a71dac9c34ed golangci-lint-1.63.4-freebsd-amd64.tar.gz +a19d499f961a02608348e8b626537a88edfaab6e1b6534f1eff742b5d6d750e4 golangci-lint-1.63.4-freebsd-armv6.tar.gz +00d616f0fb275b780ce4d26604bdd7fdbfe6bc9c63acd5a0b31498e1f7511108 golangci-lint-1.63.4-freebsd-armv7.tar.gz +d453688e0eabded3c1a97ff5a2777bb0df5a18851efdaaaf6b472e3e5713c33e golangci-lint-1.63.4-illumos-amd64.tar.gz +6b1bec847fc9f347d53712d05606a49d55d0e3b5c1bacadfed2393f3503de0e9 golangci-lint-1.63.4-linux-386.tar.gz +01abb14a4df47b5ca585eff3c34b105023cba92ec34ff17212dbb83855581690 golangci-lint-1.63.4-linux-amd64.tar.gz +51f0c79d19a92353e0465fb30a4901a0644a975d34e6f399ad2eebc0160bbb24 golangci-lint-1.63.4-linux-arm64.tar.gz +8d0a43f41e8424fbae10f7aa2dc29999f98112817c6dba63d7dc76832940a673 golangci-lint-1.63.4-linux-armv6.tar.gz +1045a047b31e9302c9160c7b0f199f4ac1bd02a1b221a2d9521bd3507f0cf671 golangci-lint-1.63.4-linux-armv7.tar.gz +933fe10ab50ce3bb0806e15a4ae69fe20f0549abf91dea0161236000ca706e67 golangci-lint-1.63.4-linux-loong64.tar.gz +45798630cbad5642862766051199fa862ef3c33d569cab12f01cac4f68e2ddd5 golangci-lint-1.63.4-linux-mips64.tar.gz +86ae25335ddb24975d2c915c1af0c7fad70dce99d0b4614fa4bee392de714aa2 golangci-lint-1.63.4-linux-mips64le.tar.gz +33dabd11aaba4b602938da98bcf49aabab55019557e0115cdc3dbcc3009768fa golangci-lint-1.63.4-linux-ppc64le.tar.gz +4e7a81230a663bcdf30bba5689ce96040abc76994dbc2003dce32c8dca8c06f3 golangci-lint-1.63.4-linux-riscv64.tar.gz +21370b49c7c47f4d9b8f982c952f940b01e65710174c3b4dad7b6452d58f92ec golangci-lint-1.63.4-linux-s390x.tar.gz +255866a6464c7e11bb7edd8e6e6ad54f11e1f01b82ba9ca229698ac788cd9724 golangci-lint-1.63.4-netbsd-386.tar.gz +2798c040ac658bda97224f204795199c81ac97bb207b21c02b664aaed380d5d2 golangci-lint-1.63.4-netbsd-amd64.tar.gz +b910eecffd0064103837e7e1abe870deb8ade22331e6dffe319f430d49399c8e golangci-lint-1.63.4-netbsd-arm64.tar.gz +df2693ef37147b457c3e2089614537dd2ae2e18e53641e756a5b404f4c72d3fa golangci-lint-1.63.4-netbsd-armv6.tar.gz +a28a533366974bd7834c4516cd6075bff3419a508d1ed7aa63ae8182768b352e golangci-lint-1.63.4-netbsd-armv7.tar.gz +368932775fb5c620b324dabf018155f3365f5e33c5af5b26e9321db373f96eea golangci-lint-1.63.4-windows-386.zip +184d13c2b8f5441576bec2a0d8ba7b2d45445595cf796b879a73bcc98c39f8c1 golangci-lint-1.63.4-windows-amd64.zip +4fabf175d5b05ef0858ded49527948eebac50e9093814979fd84555a75fb80a6 golangci-lint-1.63.4-windows-arm64.zip +e92be3f3ff30d4a849fb4b9a4c8d56837dee45269cb405a3ecad52fa034c781b golangci-lint-1.63.4-windows-armv6.zip +c71d348653b8f7fbb109bb10c1a481722bc6b0b2b6e731b897f99ac869f7653e golangci-lint-1.63.4-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 02d339f99c..4ab14bbcc0 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -1751,7 +1751,7 @@ func (p *BlobPool) Clear() { // The transaction addition may attempt to reserve the sender addr which // can't happen until Clear releases the reservation lock. Clear cannot // acquire the subpool lock until the transaction addition is completed. - for acct, _ := range p.index { + for acct := range p.index { p.reserve(acct, false) } p.lookup = newLookup() diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 70be7034ee..71cca7d1db 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1986,7 +1986,7 @@ func (pool *LegacyPool) Clear() { senderAddr, _ := types.Sender(pool.signer, tx) pool.reserve(senderAddr, false) } - for localSender, _ := range pool.locals.accounts { + for localSender := range pool.locals.accounts { pool.reserve(localSender, false) } From f460f019e9d81808bf8a15b7d7f1134ab456fb4f Mon Sep 17 00:00:00 2001 From: Martin Redmond <21436+reds@users.noreply.github.com> Date: Mon, 13 Jan 2025 10:12:15 -0500 Subject: [PATCH 10/17] eth/tracers/logger: return revert reason (#31013) Fix the error comparison in tracer to prevent dropping revert reason data --------- Co-authored-by: Martin Co-authored-by: rjl493456442 --- eth/tracers/logger/logger.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 07de871f14..596ee97146 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -19,6 +19,7 @@ package logger import ( "encoding/hex" "encoding/json" + "errors" "fmt" "io" "maps" @@ -350,7 +351,7 @@ func (l *StructLogger) GetResult() (json.RawMessage, error) { returnData := common.CopyBytes(l.output) // Return data when successful and revert reason when reverted, otherwise empty. returnVal := fmt.Sprintf("%x", returnData) - if failed && l.err != vm.ErrExecutionReverted { + if failed && !errors.Is(l.err, vm.ErrExecutionReverted) { returnVal = "" } return json.Marshal(&ExecutionResult{ From 8752785a9889a09abc6dd7354b9747caecdafa97 Mon Sep 17 00:00:00 2001 From: dashangcun <907225865@qq.com> Date: Mon, 13 Jan 2025 18:00:25 +0100 Subject: [PATCH 11/17] cmd/devp2p/internal/ethtest: using slices.SortFunc to simplify the code (#31012) Co-authored-by: Felix Lange --- cmd/devp2p/internal/ethtest/chain.go | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/chain.go b/cmd/devp2p/internal/ethtest/chain.go index 2a70e0328f..222c66d4df 100644 --- a/cmd/devp2p/internal/ethtest/chain.go +++ b/cmd/devp2p/internal/ethtest/chain.go @@ -28,7 +28,6 @@ import ( "os" "path/filepath" "slices" - "sort" "strings" "github.com/ethereum/go-ethereum/common" @@ -41,6 +40,7 @@ import ( "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/exp/maps" ) // Chain is a lightweight blockchain-like store which can read a hivechain @@ -166,11 +166,8 @@ func (c *Chain) RootAt(height int) common.Hash { // GetSender returns the address associated with account at the index in the // pre-funded accounts list. func (c *Chain) GetSender(idx int) (common.Address, uint64) { - var accounts Addresses - for addr := range c.senders { - accounts = append(accounts, addr) - } - sort.Sort(accounts) + accounts := maps.Keys(c.senders) + slices.SortFunc(accounts, common.Address.Cmp) addr := accounts[idx] return addr, c.senders[addr].Nonce } @@ -260,22 +257,6 @@ func loadGenesis(genesisFile string) (core.Genesis, error) { return gen, nil } -type Addresses []common.Address - -func (a Addresses) Len() int { - return len(a) -} - -func (a Addresses) Less(i, j int) bool { - return bytes.Compare(a[i][:], a[j][:]) < 0 -} - -func (a Addresses) Swap(i, j int) { - tmp := a[i] - a[i] = a[j] - a[j] = tmp -} - func blocksFromFile(chainfile string, gblock *types.Block) ([]*types.Block, error) { // Load chain.rlp. fh, err := os.Open(chainfile) From fcf5204a02c8b80ad3c53274374a14ef45d83e2d Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Mon, 13 Jan 2025 19:33:49 +0100 Subject: [PATCH 12/17] core/txpool/legacypool: fix flaky test TestAllowedTxSize (#30975) - it was failing because the maximum data length (previously `dataSize`) was set to `txMaxSize - 213` but should had been `txMaxSize - 103` and the last call `dataSize+1+uint64(rand.Intn(10*txMaxSize)))` would sometimes fail depending on rand.Intn. - Maximal transaction data size comment (invalid) replaced by code logic to find the maximum tx length without its data length - comments and variable naming improved for clarity - 3rd pool add test replaced to add just 1 above the maximum length, which is important to ensure the logic is correct --- core/txpool/legacypool/legacypool_test.go | 31 ++++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 39673d176d..abbde8cae3 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -1243,33 +1243,28 @@ func TestAllowedTxSize(t *testing.T) { account := crypto.PubkeyToAddress(key.PublicKey) testAddBalance(pool, account, big.NewInt(1000000000)) - // Compute maximal data size for transactions (lower bound). - // - // It is assumed the fields in the transaction (except of the data) are: - // - nonce <= 32 bytes - // - gasTip <= 32 bytes - // - gasLimit <= 32 bytes - // - recipient == 20 bytes - // - value <= 32 bytes - // - signature == 65 bytes - // All those fields are summed up to at most 213 bytes. - baseSize := uint64(213) - dataSize := txMaxSize - baseSize + // Find the maximum data length for the kind of transaction which will + // be generated in the pool.addRemoteSync calls below. + const largeDataLength = txMaxSize - 200 // enough to have a 5 bytes RLP encoding of the data length number + txWithLargeData := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, largeDataLength) + maxTxLengthWithoutData := txWithLargeData.Size() - largeDataLength // 103 bytes + maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130953 bytes + // Try adding a transaction with maximal allowed size - tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize) + tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength) if err := pool.addRemoteSync(tx); err != nil { t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err) } // Try adding a transaction with random allowed size - if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil { + if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(maxTxDataLength+1))))); err != nil { t.Fatalf("failed to add transaction of random allowed size: %v", err) } - // Try adding a transaction of minimal not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, txMaxSize)); err == nil { + // Try adding a transaction above maximum size by one + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength+1)); err == nil { t.Fatalf("expected rejection on slightly oversize transaction") } - // Try adding a transaction of random not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(10*txMaxSize)))); err == nil { + // Try adding a transaction above maximum size by more than one + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength+1+uint64(rand.Intn(10*txMaxSize)))); err == nil { t.Fatalf("expected rejection on oversize transaction") } // Run some sanity checks on the pool internals From 864e717b56e80a4970700fd50fe10188b98d670d Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Mon, 13 Jan 2025 19:35:49 +0100 Subject: [PATCH 13/17] core: remove unused function parameters (#31001) --- core/blockchain_test.go | 17 ++++------------- core/state_transition.go | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index fc0e3d8446..f2a9b953a1 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -2535,7 +2535,7 @@ func testReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T, scheme strin } // Benchmarks large blocks with value transfers to non-existing accounts -func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) { +func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address) { var ( signer = types.HomesteadSigner{} testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -2598,10 +2598,7 @@ func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) { recipientFn := func(nonce uint64) common.Address { return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce)) } - dataFn := func(nonce uint64) []byte { - return nil - } - benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn) } func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { @@ -2615,10 +2612,7 @@ func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { recipientFn := func(nonce uint64) common.Address { return common.BigToAddress(new(big.Int).SetUint64(1337)) } - dataFn := func(nonce uint64) []byte { - return nil - } - benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn) } func BenchmarkBlockChain_1x1000Executions(b *testing.B) { @@ -2632,10 +2626,7 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) { recipientFn := func(nonce uint64) common.Address { return common.BigToAddress(new(big.Int).SetUint64(0xc0de)) } - dataFn := func(nonce uint64) []byte { - return nil - } - benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn) } // Tests that importing a some old blocks, where all blocks are before the diff --git a/core/state_transition.go b/core/state_transition.go index 93d72d16b7..009b679b27 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -470,7 +470,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { if msg.SetCodeAuthorizations != nil { for _, auth := range msg.SetCodeAuthorizations { // Note errors are ignored, we simply skip invalid authorizations here. - st.applyAuthorization(msg, &auth) + st.applyAuthorization(&auth) } } @@ -559,7 +559,7 @@ func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorizatio } // applyAuthorization applies an EIP-7702 code delegation to the state. -func (st *stateTransition) applyAuthorization(msg *Message, auth *types.SetCodeAuthorization) error { +func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) error { authority, err := st.validateAuthorization(auth) if err != nil { return err From 37c0e6992e02190c4e6a3bc9d70c19967f8931db Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 14 Jan 2025 18:49:30 +0800 Subject: [PATCH 14/17] cmd, core, miner: rework genesis setup (#30907) This pull request refactors the genesis setup function, the major changes are highlighted here: **(a) Triedb is opened in verkle mode if `EnableVerkleAtGenesis` is configured in chainConfig or the database has been initialized previously with `EnableVerkleAtGenesis` configured**. A new config field `EnableVerkleAtGenesis` has been added in the chainConfig. This field must be configured with True if Geth wants to initialize the genesis in Verkle mode. In the verkle devnet-7, the verkle transition is activated at genesis. Therefore, the verkle rules should be used since the genesis. In production networks (mainnet and public testnets), verkle activation always occurs after the genesis block. Therefore, this flag is only made for devnet and should be deprecated later. Besides, verkle transition at non-genesis block hasn't been implemented yet, it should be done in the following PRs. **(b) The genesis initialization condition has been simplified** There is a special mode supported by the Geth is that: Geth can be initialized with an existing chain segment, which can fasten the node sync process by retaining the chain freezer folder. Originally, if the triedb is regarded as uninitialized and the genesis block can be found in the chain freezer, the genesis block along with genesis state will be committed. This condition has been simplified to checking the presence of chain config in key-value store. The existence of chain config can represent the genesis has been committed. --- cmd/geth/chaincmd.go | 3 +- cmd/utils/history_test.go | 2 +- core/blockchain.go | 31 +++--- core/genesis.go | 202 +++++++++++++++++++++--------------- core/genesis_test.go | 41 ++++---- core/verkle_witness_test.go | 2 + miner/miner_test.go | 2 +- params/config.go | 27 +++++ triedb/database.go | 10 -- triedb/hashdb/database.go | 6 -- triedb/pathdb/database.go | 15 --- 11 files changed, 191 insertions(+), 150 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 48564eb5eb..bbadb1cc19 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -230,11 +230,10 @@ func initGenesis(ctx *cli.Context) error { triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) defer triedb.Close() - _, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + _, hash, _, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) if err != nil { utils.Fatalf("Failed to write genesis block: %v", err) } - log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash) return nil diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index 1074a358ec..07cf71234e 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -170,7 +170,7 @@ func TestHistoryImportAndExport(t *testing.T) { db2.Close() }) - genesis.MustCommit(db2, triedb.NewDatabase(db, triedb.HashDefaults)) + genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults)) imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil) if err != nil { t.Fatalf("unable to initialize chain: %v", err) diff --git a/core/blockchain.go b/core/blockchain.go index 0fe4812626..b056b7ed0c 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -269,14 +269,19 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis cacheConfig = defaultCacheConfig } // Open trie database with provided config - triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(genesis != nil && genesis.IsVerkle())) + enableVerkle, err := EnableVerkleAtGenesis(db, genesis) + if err != nil { + return nil, err + } + triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(enableVerkle)) - // Setup the genesis block, commit the provided genesis specification - // to database if the genesis block is not present yet, or load the - // stored one from database. - chainConfig, genesisHash, genesisErr := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides) - if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { - return nil, genesisErr + // Write the supplied genesis to the database if it has not been initialized + // yet. The corresponding chain config will be returned, either from the + // provided genesis or from the locally stored configuration if the genesis + // has already been initialized. + chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides) + if err != nil { + return nil, err } log.Info("") log.Info(strings.Repeat("-", 153)) @@ -303,7 +308,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis vmConfig: vmConfig, logger: vmConfig.Tracer, } - var err error bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped) if err != nil { return nil, err @@ -453,16 +457,15 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis } // Rewind the chain in case of an incompatible config upgrade. - if compat, ok := genesisErr.(*params.ConfigCompatError); ok { - log.Warn("Rewinding chain to upgrade configuration", "err", compat) - if compat.RewindToTime > 0 { - bc.SetHeadWithTimestamp(compat.RewindToTime) + if compatErr != nil { + log.Warn("Rewinding chain to upgrade configuration", "err", compatErr) + if compatErr.RewindToTime > 0 { + bc.SetHeadWithTimestamp(compatErr.RewindToTime) } else { - bc.SetHead(compat.RewindToBlock) + bc.SetHead(compatErr.RewindToBlock) } rawdb.WriteChainConfig(db, genesisHash, chainConfig) } - // Start tx indexer if it's enabled. if txLookupLimit != nil { bc.txIndexer = newTxIndexer(*txLookupLimit, bc) diff --git a/core/genesis.go b/core/genesis.go index 347789cf0c..02cdc74d86 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -247,6 +247,24 @@ type ChainOverrides struct { OverrideVerkle *uint64 } +// apply applies the chain overrides on the supplied chain config. +func (o *ChainOverrides) apply(cfg *params.ChainConfig) (*params.ChainConfig, error) { + if o == nil || cfg == nil { + return cfg, nil + } + cpy := *cfg + if o.OverrideCancun != nil { + cpy.CancunTime = o.OverrideCancun + } + if o.OverrideVerkle != nil { + cpy.VerkleTime = o.OverrideVerkle + } + if err := cpy.CheckConfigForkOrder(); err != nil { + return nil, err + } + return &cpy, nil +} + // SetupGenesisBlock writes or updates the genesis block in db. // The block that will be used is: // @@ -258,109 +276,102 @@ type ChainOverrides struct { // The stored chain configuration will be updated if it is compatible (i.e. does not // specify a fork block below the local head block). In case of a conflict, the // error is a *params.ConfigCompatError and the new, unwritten config is returned. -// -// The returned chain configuration is never nil. -func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { +func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { return SetupGenesisBlockWithOverride(db, triedb, genesis, nil) } -func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, error) { +func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + // Sanitize the supplied genesis, ensuring it has the associated chain + // config attached. if genesis != nil && genesis.Config == nil { - return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig + return nil, common.Hash{}, nil, errGenesisNoConfig } - applyOverrides := func(config *params.ChainConfig) { - if config != nil { - if overrides != nil && overrides.OverrideCancun != nil { - config.CancunTime = overrides.OverrideCancun - } - if overrides != nil && overrides.OverrideVerkle != nil { - config.VerkleTime = overrides.OverrideVerkle - } - } - } - // Just commit the new block if there is no stored genesis block. - stored := rawdb.ReadCanonicalHash(db, 0) - if (stored == common.Hash{}) { + // Commit the genesis if the database is empty + ghash := rawdb.ReadCanonicalHash(db, 0) + if (ghash == common.Hash{}) { if genesis == nil { log.Info("Writing default main-net genesis block") genesis = DefaultGenesisBlock() } else { log.Info("Writing custom genesis block") } + chainCfg, err := overrides.apply(genesis.Config) + if err != nil { + return nil, common.Hash{}, nil, err + } + genesis.Config = chainCfg - applyOverrides(genesis.Config) block, err := genesis.Commit(db, triedb) if err != nil { - return genesis.Config, common.Hash{}, err + return nil, common.Hash{}, nil, err } - return genesis.Config, block.Hash(), nil + return chainCfg, block.Hash(), nil, nil } - // The genesis block is present(perhaps in ancient database) while the - // state database is not initialized yet. It can happen that the node - // is initialized with an external ancient store. Commit genesis state - // in this case. - header := rawdb.ReadHeader(db, stored, 0) - if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) { + // Commit the genesis if the genesis block exists in the ancient database + // but the key-value database is empty without initializing the genesis + // fields. This scenario can occur when the node is created from scratch + // with an existing ancient store. + storedCfg := rawdb.ReadChainConfig(db, ghash) + if storedCfg == nil { + // Ensure the stored genesis block matches with the given genesis. Private + // networks must explicitly specify the genesis in the config file, mainnet + // genesis will be used as default and the initialization will always fail. if genesis == nil { + log.Info("Writing default main-net genesis block") genesis = DefaultGenesisBlock() + } else { + log.Info("Writing custom genesis block") } - applyOverrides(genesis.Config) - // Ensure the stored genesis matches with the given one. - hash := genesis.ToBlock().Hash() - if hash != stored { - return genesis.Config, hash, &GenesisMismatchError{stored, hash} + chainCfg, err := overrides.apply(genesis.Config) + if err != nil { + return nil, common.Hash{}, nil, err + } + genesis.Config = chainCfg + + if hash := genesis.ToBlock().Hash(); hash != ghash { + return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } block, err := genesis.Commit(db, triedb) if err != nil { - return genesis.Config, hash, err + return nil, common.Hash{}, nil, err } - return genesis.Config, block.Hash(), nil + return chainCfg, block.Hash(), nil, nil } - // Check whether the genesis block is already written. + // The genesis block has already been committed previously. Verify that the + // provided genesis with chain overrides matches the existing one, and update + // the stored chain config if necessary. if genesis != nil { - applyOverrides(genesis.Config) - hash := genesis.ToBlock().Hash() - if hash != stored { - return genesis.Config, hash, &GenesisMismatchError{stored, hash} + chainCfg, err := overrides.apply(genesis.Config) + if err != nil { + return nil, common.Hash{}, nil, err + } + genesis.Config = chainCfg + + if hash := genesis.ToBlock().Hash(); hash != ghash { + return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } - } - // Get the existing chain configuration. - newcfg := genesis.configOrDefault(stored) - applyOverrides(newcfg) - if err := newcfg.CheckConfigForkOrder(); err != nil { - return newcfg, common.Hash{}, err - } - storedcfg := rawdb.ReadChainConfig(db, stored) - if storedcfg == nil { - log.Warn("Found genesis block without chain config") - rawdb.WriteChainConfig(db, stored, newcfg) - return newcfg, stored, nil - } - storedData, _ := json.Marshal(storedcfg) - // Special case: if a private network is being used (no genesis and also no - // mainnet hash in the database), we must not apply the `configOrDefault` - // chain config as that would be AllProtocolChanges (applying any new fork - // on top of an existing private network genesis block). In that case, only - // apply the overrides. - if genesis == nil && stored != params.MainnetGenesisHash { - newcfg = storedcfg - applyOverrides(newcfg) } // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. head := rawdb.ReadHeadHeader(db) if head == nil { - return newcfg, stored, errors.New("missing head header") + return nil, common.Hash{}, nil, errors.New("missing head header") } - compatErr := storedcfg.CheckCompatible(newcfg, head.Number.Uint64(), head.Time) + newCfg := genesis.chainConfigOrDefault(ghash, storedCfg) + + // TODO(rjl493456442) better to define the comparator of chain config + // and short circuit if the chain config is not changed. + compatErr := storedCfg.CheckCompatible(newCfg, head.Number.Uint64(), head.Time) if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) { - return newcfg, stored, compatErr + return newCfg, ghash, compatErr, nil } - // Don't overwrite if the old is identical to the new - if newData, _ := json.Marshal(newcfg); !bytes.Equal(storedData, newData) { - rawdb.WriteChainConfig(db, stored, newcfg) + // Don't overwrite if the old is identical to the new. It's useful + // for the scenarios that database is opened in the read-only mode. + storedData, _ := json.Marshal(storedCfg) + if newData, _ := json.Marshal(newCfg); !bytes.Equal(storedData, newData) { + rawdb.WriteChainConfig(db, ghash, newCfg) } - return newcfg, stored, nil + return newCfg, ghash, nil, nil } // LoadChainConfig loads the stored chain config if it is already present in @@ -396,7 +407,10 @@ func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, return params.MainnetChainConfig, nil } -func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { +// chainConfigOrDefault retrieves the attached chain configuration. If the genesis +// object is null, it returns the default chain configuration based on the given +// genesis hash, or the locally stored config if it's not a pre-defined network. +func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainConfig) *params.ChainConfig { switch { case g != nil: return g.Config @@ -407,14 +421,14 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { case ghash == params.SepoliaGenesisHash: return params.SepoliaChainConfig default: - return params.AllEthashProtocolChanges + return stored } } // IsVerkle indicates whether the state is already stored in a verkle // tree at genesis time. func (g *Genesis) IsVerkle() bool { - return g.Config.IsVerkle(new(big.Int).SetUint64(g.Number), g.Timestamp) + return g.Config.IsVerkleGenesis() } // ToBlock returns the genesis block according to genesis specification. @@ -494,7 +508,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo } config := g.Config if config == nil { - config = params.AllEthashProtocolChanges + return nil, errors.New("invalid genesis without chain config") } if err := config.CheckConfigForkOrder(); err != nil { return nil, err @@ -514,16 +528,17 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo if err != nil { return nil, err } - rawdb.WriteGenesisStateSpec(db, block.Hash(), blob) - rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty()) - rawdb.WriteBlock(db, block) - rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) - rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) - rawdb.WriteHeadBlockHash(db, block.Hash()) - rawdb.WriteHeadFastBlockHash(db, block.Hash()) - rawdb.WriteHeadHeaderHash(db, block.Hash()) - rawdb.WriteChainConfig(db, block.Hash(), config) - return block, nil + batch := db.NewBatch() + rawdb.WriteGenesisStateSpec(batch, block.Hash(), blob) + rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), block.Difficulty()) + rawdb.WriteBlock(batch, block) + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), nil) + rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64()) + rawdb.WriteHeadBlockHash(batch, block.Hash()) + rawdb.WriteHeadFastBlockHash(batch, block.Hash()) + rawdb.WriteHeadHeaderHash(batch, block.Hash()) + rawdb.WriteChainConfig(batch, block.Hash(), config) + return block, batch.Write() } // MustCommit writes the genesis block and state to db, panicking on error. @@ -536,6 +551,29 @@ func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types. return block } +// EnableVerkleAtGenesis indicates whether the verkle fork should be activated +// at genesis. This is a temporary solution only for verkle devnet testing, where +// verkle fork is activated at genesis, and the configured activation date has +// already passed. +// +// In production networks (mainnet and public testnets), verkle activation always +// occurs after the genesis block, making this function irrelevant in those cases. +func EnableVerkleAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) { + if genesis != nil { + if genesis.Config == nil { + return false, errGenesisNoConfig + } + return genesis.Config.EnableVerkleAtGenesis, nil + } + if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) { + chainCfg := rawdb.ReadChainConfig(db, ghash) + if chainCfg != nil { + return chainCfg.EnableVerkleAtGenesis, nil + } + } + return false, nil +} + // DefaultGenesisBlock returns the Ethereum main net genesis block. func DefaultGenesisBlock() *Genesis { return &Genesis{ diff --git a/core/genesis_test.go b/core/genesis_test.go index 3ec87474e5..964ef928c7 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -54,23 +54,23 @@ func testSetupGenesis(t *testing.T, scheme string) { oldcustomg.Config = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(2)} tests := []struct { - name string - fn func(ethdb.Database) (*params.ChainConfig, common.Hash, error) - wantConfig *params.ChainConfig - wantHash common.Hash - wantErr error + name string + fn func(ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) + wantConfig *params.ChainConfig + wantHash common.Hash + wantErr error + wantCompactErr *params.ConfigCompatError }{ { name: "genesis without ChainConfig", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), new(Genesis)) }, - wantErr: errGenesisNoConfig, - wantConfig: params.AllEthashProtocolChanges, + wantErr: errGenesisNoConfig, }, { name: "no block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil) }, wantHash: params.MainnetGenesisHash, @@ -78,7 +78,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "mainnet block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { DefaultGenesisBlock().MustCommit(db, triedb.NewDatabase(db, newDbConfig(scheme))) return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil) }, @@ -87,7 +87,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "custom block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) customg.Commit(db, tdb) return SetupGenesisBlock(db, tdb, nil) @@ -97,18 +97,16 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "custom block in DB, genesis == sepolia", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) customg.Commit(db, tdb) return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock()) }, - wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, - wantHash: params.SepoliaGenesisHash, - wantConfig: params.SepoliaChainConfig, + wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, }, { name: "compatible config in DB", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) oldcustomg.Commit(db, tdb) return SetupGenesisBlock(db, tdb, &customg) @@ -118,7 +116,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, { name: "incompatible config in DB", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { + fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { // Commit the 'old' genesis block with Homestead transition at #2. // Advance to block #4, past the homestead transition block of customg. tdb := triedb.NewDatabase(db, newDbConfig(scheme)) @@ -135,7 +133,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, wantHash: customghash, wantConfig: customg.Config, - wantErr: ¶ms.ConfigCompatError{ + wantCompactErr: ¶ms.ConfigCompatError{ What: "Homestead fork block", StoredBlock: big.NewInt(2), NewBlock: big.NewInt(3), @@ -146,12 +144,16 @@ func testSetupGenesis(t *testing.T, scheme string) { for _, test := range tests { db := rawdb.NewMemoryDatabase() - config, hash, err := test.fn(db) + config, hash, compatErr, err := test.fn(db) // Check the return values. if !reflect.DeepEqual(err, test.wantErr) { spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true} t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr)) } + if !reflect.DeepEqual(compatErr, test.wantCompactErr) { + spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true} + t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(compatErr), spew.NewFormatter(test.wantCompactErr)) + } if !reflect.DeepEqual(config, test.wantConfig) { t.Errorf("%s:\nreturned %v\nwant %v", test.name, config, test.wantConfig) } @@ -279,6 +281,7 @@ func TestVerkleGenesisCommit(t *testing.T) { PragueTime: &verkleTime, VerkleTime: &verkleTime, TerminalTotalDifficulty: big.NewInt(0), + EnableVerkleAtGenesis: true, Ethash: nil, Clique: nil, } diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 5088231207..02e94963c4 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -57,6 +57,7 @@ var ( ShanghaiTime: u64(0), VerkleTime: u64(0), TerminalTotalDifficulty: common.Big0, + EnableVerkleAtGenesis: true, // TODO uncomment when proof generation is merged // ProofInBlocks: true, } @@ -77,6 +78,7 @@ var ( ShanghaiTime: u64(0), VerkleTime: u64(0), TerminalTotalDifficulty: common.Big0, + EnableVerkleAtGenesis: true, } ) diff --git a/miner/miner_test.go b/miner/miner_test.go index b92febdd12..04d84e2e1d 100644 --- a/miner/miner_test.go +++ b/miner/miner_test.go @@ -145,7 +145,7 @@ func createMiner(t *testing.T) *Miner { chainDB := rawdb.NewMemoryDatabase() triedb := triedb.NewDatabase(chainDB, nil) genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345")) - chainConfig, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) + chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) if err != nil { t.Fatalf("can't create new chain config: %v", err) } diff --git a/params/config.go b/params/config.go index 9b3b92484a..f1e139608c 100644 --- a/params/config.go +++ b/params/config.go @@ -326,6 +326,19 @@ type ChainConfig struct { DepositContractAddress common.Address `json:"depositContractAddress,omitempty"` + // EnableVerkleAtGenesis is a flag that specifies whether the network uses + // the Verkle tree starting from the genesis block. If set to true, the + // genesis state will be committed using the Verkle tree, eliminating the + // need for any Verkle transition later. + // + // This is a temporary flag only for verkle devnet testing, where verkle is + // activated at genesis, and the configured activation date has already passed. + // + // In production networks (mainnet and public testnets), verkle activation + // always occurs after the genesis block, making this flag irrelevant in + // those cases. + EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"` + // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` @@ -525,6 +538,20 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) } +// IsVerkleGenesis checks whether the verkle fork is activated at the genesis block. +// +// Verkle mode is considered enabled if the verkle fork time is configured, +// regardless of whether the local time has surpassed the fork activation time. +// This is a temporary workaround for verkle devnet testing, where verkle is +// activated at genesis, and the configured activation date has already passed. +// +// In production networks (mainnet and public testnets), verkle activation +// always occurs after the genesis block, making this function irrelevant in +// those cases. +func (c *ChainConfig) IsVerkleGenesis() bool { + return c.EnableVerkleAtGenesis +} + // IsEIP4762 returns whether eip 4762 has been activated at given block. func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool { return c.IsVerkle(num, time) diff --git a/triedb/database.go b/triedb/database.go index b448d7cd07..f8ccc5ad33 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -64,10 +64,6 @@ type backend interface { // state. An error will be returned if the specified state is not available. StateReader(root common.Hash) (database.StateReader, error) - // Initialized returns an indicator if the state data is already initialized - // according to the state scheme. - Initialized(genesisRoot common.Hash) bool - // Size returns the current storage size of the diff layers on top of the // disk layer and the storage size of the nodes cached in the disk layer. // @@ -178,12 +174,6 @@ func (db *Database) Size() (common.StorageSize, common.StorageSize, common.Stora return diffs, nodes, preimages } -// Initialized returns an indicator if the state data is already initialized -// according to the state scheme. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - return db.backend.Initialized(genesisRoot) -} - // Scheme returns the node scheme used in the database. func (db *Database) Scheme() string { if db.config.PathDB != nil { diff --git a/triedb/hashdb/database.go b/triedb/hashdb/database.go index fb718f4e74..38392aa519 100644 --- a/triedb/hashdb/database.go +++ b/triedb/hashdb/database.go @@ -532,12 +532,6 @@ func (c *cleaner) Delete(key []byte) error { panic("not implemented") } -// Initialized returns an indicator if state data is already initialized -// in hash-based scheme by checking the presence of genesis state. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - return rawdb.HasLegacyTrieNode(db.diskdb, genesisRoot) -} - // Update inserts the dirty nodes in provided nodeset into database and link the // account trie with multiple storage tries if necessary. func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet) error { diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index c31f1d44f4..b0d84eb879 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -529,21 +529,6 @@ func (db *Database) Size() (diffs common.StorageSize, nodes common.StorageSize) return diffs, nodes } -// Initialized returns an indicator if the state data is already -// initialized in path-based scheme. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - var inited bool - db.tree.forEach(func(layer layer) { - if layer.rootHash() != types.EmptyRootHash { - inited = true - } - }) - if !inited { - inited = rawdb.ReadSnapSyncStatusFlag(db.diskdb) != rawdb.StateSyncUnknown - } - return inited -} - // modifyAllowed returns the indicator if mutation is allowed. This function // assumes the db.lock is already held. func (db *Database) modifyAllowed() error { From 1843f2776603ed1b66bfe78916d61267f80201e7 Mon Sep 17 00:00:00 2001 From: georgehao Date: Tue, 14 Jan 2025 21:16:15 +0800 Subject: [PATCH 15/17] all: fix some typos in comments and names (#31023) --- accounts/accounts.go | 4 +++- cmd/devp2p/internal/ethtest/protocol.go | 1 + cmd/devp2p/internal/v4test/discv4tests.go | 18 ++++++++-------- consensus/clique/snapshot_test.go | 1 - core/tracing/hooks.go | 2 +- core/txpool/legacypool/legacypool2_test.go | 6 +++--- core/types/deposit.go | 2 +- core/vm/eof_validation.go | 6 +++--- core/vm/program/program.go | 5 +++-- crypto/blake2b/blake2b.go | 8 +++---- crypto/bn256/gnark/pairing.go | 2 +- crypto/ecies/ecies.go | 12 +++++------ eth/tracers/dir.go | 2 +- eth/tracers/internal/util.go | 1 + internal/era/builder.go | 3 ++- internal/jsre/jsre.go | 25 +++++++++++++++++++--- internal/reexec/reexec.go | 1 + metrics/exp/exp.go | 1 + metrics/gauge_info.go | 2 +- metrics/log.go | 2 +- metrics/metrics.go | 1 + metrics/resetting_timer.go | 6 +++--- metrics/syslog.go | 2 +- p2p/discover/v5wire/encoding_test.go | 12 +++++------ params/protocol_params.go | 2 +- signer/core/api.go | 2 +- signer/core/uiapi.go | 2 +- 27 files changed, 79 insertions(+), 52 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index b995498a6d..7bd911577a 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -214,7 +214,9 @@ const ( // of starting any background processes such as automatic key derivation. WalletOpened - // WalletDropped + // WalletDropped is fired when a wallet is removed or disconnected, either via USB + // or due to a filesystem event in the keystore. This event indicates that the wallet + // is no longer available for operations. WalletDropped ) diff --git a/cmd/devp2p/internal/ethtest/protocol.go b/cmd/devp2p/internal/ethtest/protocol.go index f5f5f7e489..5c2f7d9e48 100644 --- a/cmd/devp2p/internal/ethtest/protocol.go +++ b/cmd/devp2p/internal/ethtest/protocol.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . + package ethtest import ( diff --git a/cmd/devp2p/internal/v4test/discv4tests.go b/cmd/devp2p/internal/v4test/discv4tests.go index ca556851b4..963df6cdbc 100644 --- a/cmd/devp2p/internal/v4test/discv4tests.go +++ b/cmd/devp2p/internal/v4test/discv4tests.go @@ -194,7 +194,7 @@ func PingExtraData(t *utesting.T) { } } -// This test sends a PING packet with additional data and wrong 'from' field +// PingExtraDataWrongFrom sends a PING packet with additional data and wrong 'from' field // and expects a PONG response. func PingExtraDataWrongFrom(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -215,7 +215,7 @@ func PingExtraDataWrongFrom(t *utesting.T) { } } -// This test sends a PING packet with an expiration in the past. +// PingPastExpiration sends a PING packet with an expiration in the past. // The remote node should not respond. func PingPastExpiration(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -234,7 +234,7 @@ func PingPastExpiration(t *utesting.T) { } } -// This test sends an invalid packet. The remote node should not respond. +// WrongPacketType sends an invalid packet. The remote node should not respond. func WrongPacketType(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) defer te.close() @@ -252,7 +252,7 @@ func WrongPacketType(t *utesting.T) { } } -// This test verifies that the default behaviour of ignoring 'from' fields is unaffected by +// BondThenPingWithWrongFrom verifies that the default behaviour of ignoring 'from' fields is unaffected by // the bonding process. After bonding, it pings the target with a different from endpoint. func BondThenPingWithWrongFrom(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -289,7 +289,7 @@ waitForPong: } } -// This test just sends FINDNODE. The remote node should not reply +// FindnodeWithoutEndpointProof sends FINDNODE. The remote node should not reply // because the endpoint proof has not completed. func FindnodeWithoutEndpointProof(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -332,7 +332,7 @@ func BasicFindnode(t *utesting.T) { } } -// This test sends an unsolicited NEIGHBORS packet after the endpoint proof, then sends +// UnsolicitedNeighbors sends an unsolicited NEIGHBORS packet after the endpoint proof, then sends // FINDNODE to read the remote table. The remote node should not return the node contained // in the unsolicited NEIGHBORS packet. func UnsolicitedNeighbors(t *utesting.T) { @@ -373,7 +373,7 @@ func UnsolicitedNeighbors(t *utesting.T) { } } -// This test sends FINDNODE with an expiration timestamp in the past. +// FindnodePastExpiration sends FINDNODE with an expiration timestamp in the past. // The remote node should not respond. func FindnodePastExpiration(t *utesting.T) { te := newTestEnv(Remote, Listen1, Listen2) @@ -426,7 +426,7 @@ func bond(t *utesting.T, te *testenv) { } } -// This test attempts to perform a traffic amplification attack against a +// FindnodeAmplificationInvalidPongHash attempts to perform a traffic amplification attack against a // 'victim' endpoint using FINDNODE. In this attack scenario, the attacker // attempts to complete the endpoint proof non-interactively by sending a PONG // with mismatching reply token from the 'victim' endpoint. The attack works if @@ -478,7 +478,7 @@ func FindnodeAmplificationInvalidPongHash(t *utesting.T) { } } -// This test attempts to perform a traffic amplification attack using FINDNODE. +// FindnodeAmplificationWrongIP attempts to perform a traffic amplification attack using FINDNODE. // The attack works if the remote node does not verify the IP address of FINDNODE // against the endpoint verification proof done by PING/PONG. func FindnodeAmplificationWrongIP(t *utesting.T) { diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go index 6c46d1db4f..a83d6ca736 100644 --- a/consensus/clique/snapshot_test.go +++ b/consensus/clique/snapshot_test.go @@ -467,7 +467,6 @@ func (tt *cliqueTest) run(t *testing.T) { for j := 0; j < len(batches)-1; j++ { if k, err := chain.InsertChain(batches[j]); err != nil { t.Fatalf("failed to import batch %d, block %d: %v", j, k, err) - break } } if _, err = chain.InsertChain(batches[len(batches)-1]); err != tt.failure { diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 728f15069b..4343edfe86 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -293,7 +293,7 @@ const ( GasChangeCallLeftOverRefunded GasChangeReason = 7 // GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE. GasChangeCallContractCreation GasChangeReason = 8 - // GasChangeContractCreation is the amount of gas that will be burned for a CREATE2. + // GasChangeCallContractCreation2 is the amount of gas that will be burned for a CREATE2. GasChangeCallContractCreation2 GasChangeReason = 9 // GasChangeCallCodeStorage is the amount of gas that will be charged for code storage. GasChangeCallCodeStorage GasChangeReason = 10 diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index 1377479da1..8af9624994 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -162,12 +162,12 @@ func TestTransactionZAttack(t *testing.T) { var ivpendingNum int pendingtxs, _ := pool.Content() for account, txs := range pendingtxs { - cur_balance := new(big.Int).Set(pool.currentState.GetBalance(account).ToBig()) + curBalance := new(big.Int).Set(pool.currentState.GetBalance(account).ToBig()) for _, tx := range txs { - if cur_balance.Cmp(tx.Value()) <= 0 { + if curBalance.Cmp(tx.Value()) <= 0 { ivpendingNum++ } else { - cur_balance.Sub(cur_balance, tx.Value()) + curBalance.Sub(curBalance, tx.Value()) } } } diff --git a/core/types/deposit.go b/core/types/deposit.go index 3bba2c7aa4..8015f29ca7 100644 --- a/core/types/deposit.go +++ b/core/types/deposit.go @@ -24,7 +24,7 @@ const ( depositRequestSize = 192 ) -// UnpackIntoDeposit unpacks a serialized DepositEvent. +// DepositLogToRequest unpacks a serialized DepositEvent. func DepositLogToRequest(data []byte) ([]byte, error) { if len(data) != 576 { return nil, fmt.Errorf("deposit wrong length: want 576, have %d", len(data)) diff --git a/core/vm/eof_validation.go b/core/vm/eof_validation.go index fa534edce9..514f9fb58c 100644 --- a/core/vm/eof_validation.go +++ b/core/vm/eof_validation.go @@ -109,8 +109,8 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable, return nil, err } case RJUMPV: - max_size := int(code[i+1]) - length := max_size + 1 + maxSize := int(code[i+1]) + length := maxSize + 1 if len(code) <= i+length { return nil, fmt.Errorf("%w: jump table truncated, op %s, pos %d", errTruncatedImmediate, op, i) } @@ -120,7 +120,7 @@ func validateCode(code []byte, section int, container *Container, jt *JumpTable, return nil, err } } - i += 2 * max_size + i += 2 * maxSize case CALLF: arg, _ := parseUint16(code[i+1:]) if arg >= len(container.types) { diff --git a/core/vm/program/program.go b/core/vm/program/program.go index acc7fd25fc..3b00bbae6f 100644 --- a/core/vm/program/program.go +++ b/core/vm/program/program.go @@ -19,6 +19,7 @@ // - There are not package guarantees. We might iterate heavily on this package, and do backwards-incompatible changes without warning // - There are no quality-guarantees. These utilities may produce evm-code that is non-functional. YMMV. // - There are no stability-guarantees. The utility will `panic` if the inputs do not align / make sense. + package program import ( @@ -204,7 +205,7 @@ func (p *Program) StaticCall(gas *uint256.Int, address, inOffset, inSize, outOff return p.Op(vm.STATICCALL) } -// StaticCall is a convenience function to make a callcode. If 'gas' is nil, the opcode GAS will +// CallCode is a convenience function to make a callcode. If 'gas' is nil, the opcode GAS will // be used to provide all gas. func (p *Program) CallCode(gas *uint256.Int, address, value, inOffset, inSize, outOffset, outSize any) *Program { if outOffset == outSize && inSize == outSize && inOffset == outSize { @@ -263,7 +264,7 @@ func (p *Program) InputAddressToStack(inputOffset uint32) *Program { return p.Op(vm.AND) } -// MStore stores the provided data (into the memory area starting at memStart). +// Mstore stores the provided data (into the memory area starting at memStart). func (p *Program) Mstore(data []byte, memStart uint32) *Program { var idx = 0 // We need to store it in chunks of 32 bytes diff --git a/crypto/blake2b/blake2b.go b/crypto/blake2b/blake2b.go index 7ecaab8139..c24a88b99d 100644 --- a/crypto/blake2b/blake2b.go +++ b/crypto/blake2b/blake2b.go @@ -23,13 +23,13 @@ import ( ) const ( - // The blocksize of BLAKE2b in bytes. + // BlockSize the blocksize of BLAKE2b in bytes. BlockSize = 128 - // The hash size of BLAKE2b-512 in bytes. + // Size the hash size of BLAKE2b-512 in bytes. Size = 64 - // The hash size of BLAKE2b-384 in bytes. + // Size384 the hash size of BLAKE2b-384 in bytes. Size384 = 48 - // The hash size of BLAKE2b-256 in bytes. + // Size256 the hash size of BLAKE2b-256 in bytes. Size256 = 32 ) diff --git a/crypto/bn256/gnark/pairing.go b/crypto/bn256/gnark/pairing.go index 39e8a657f4..439ce0a39d 100644 --- a/crypto/bn256/gnark/pairing.go +++ b/crypto/bn256/gnark/pairing.go @@ -4,7 +4,7 @@ import ( "github.com/consensys/gnark-crypto/ecc/bn254" ) -// Computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1 +// PairingCheck computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1 // // To explain why gnark returns a (bool, error): // diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index 1b6c9e97c1..76f934c72d 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -60,12 +60,12 @@ type PublicKey struct { Params *ECIESParams } -// Export an ECIES public key as an ECDSA public key. +// ExportECDSA exports an ECIES public key as an ECDSA public key. func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey { return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y} } -// Import an ECDSA public key as an ECIES public key. +// ImportECDSAPublic imports an ECDSA public key as an ECIES public key. func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey { return &PublicKey{ X: pub.X, @@ -81,20 +81,20 @@ type PrivateKey struct { D *big.Int } -// Export an ECIES private key as an ECDSA private key. +// ExportECDSA exports an ECIES private key as an ECDSA private key. func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey { pub := &prv.PublicKey pubECDSA := pub.ExportECDSA() return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D} } -// Import an ECDSA private key as an ECIES private key. +// ImportECDSA imports an ECDSA private key as an ECIES private key. func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey { pub := ImportECDSAPublic(&prv.PublicKey) return &PrivateKey{*pub, prv.D} } -// Generate an elliptic curve public / private keypair. If params is nil, +// GenerateKey generates an elliptic curve public / private keypair. If params is nil, // the recommended default parameters for the key will be chosen. func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) { sk, err := ecdsa.GenerateKey(curve, rand) @@ -119,7 +119,7 @@ func MaxSharedKeyLength(pub *PublicKey) int { return (pub.Curve.Params().BitSize + 7) / 8 } -// ECDH key agreement method used to establish secret keys for encryption. +// GenerateShared ECDH key agreement method used to establish secret keys for encryption. func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) { if prv.PublicKey.Curve != pub.Curve { return nil, ErrInvalidCurve diff --git a/eth/tracers/dir.go b/eth/tracers/dir.go index 55bcb44d23..1cdfab5454 100644 --- a/eth/tracers/dir.go +++ b/eth/tracers/dir.go @@ -34,7 +34,7 @@ type Context struct { TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) } -// The set of methods that must be exposed by a tracer +// Tracer represents the set of methods that must be exposed by a tracer // for it to be available through the RPC interface. // This involves a method to retrieve results and one to // stop tracing. diff --git a/eth/tracers/internal/util.go b/eth/tracers/internal/util.go index 347af43d51..cff6295566 100644 --- a/eth/tracers/internal/util.go +++ b/eth/tracers/internal/util.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . + package internal import ( diff --git a/internal/era/builder.go b/internal/era/builder.go index 75782a08c2..33261555ba 100644 --- a/internal/era/builder.go +++ b/internal/era/builder.go @@ -12,7 +12,8 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . +// along with go-ethereum. If not, see . + package era import ( diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go index f6e21d2ef7..0dfeae8e1b 100644 --- a/internal/jsre/jsre.go +++ b/internal/jsre/jsre.go @@ -67,7 +67,19 @@ type evalReq struct { done chan bool } -// runtime must be stopped with Stop() after use and cannot be used after stopping +// New creates and initializes a new JavaScript runtime environment (JSRE). +// The runtime is configured with the provided assetPath for loading scripts and +// an output writer for logging or printing results. +// +// The returned JSRE must be stopped by calling Stop() after use to release resources. +// Attempting to use the JSRE after stopping it will result in undefined behavior. +// +// Parameters: +// - assetPath: The path to the directory containing script assets. +// - output: The writer used for logging or printing runtime output. +// +// Returns: +// - A pointer to the newly created JSRE instance. func New(assetPath string, output io.Writer) *JSRE { re := &JSRE{ assetPath: assetPath, @@ -251,8 +263,15 @@ func (re *JSRE) Stop(waitForCallbacks bool) { } } -// Exec(file) loads and runs the contents of a file -// if a relative path is given, the jsre's assetPath is used +// Exec loads and executes the contents of a JavaScript file. +// If a relative path is provided, the file is resolved relative to the JSRE's assetPath. +// The file is read, compiled, and executed in the JSRE's runtime environment. +// +// Parameters: +// - file: The path to the JavaScript file to execute. Can be an absolute path or relative to assetPath. +// +// Returns: +// - error: An error if the file cannot be read, compiled, or executed. func (re *JSRE) Exec(file string) error { code, err := os.ReadFile(common.AbsolutePath(re.assetPath, file)) if err != nil { diff --git a/internal/reexec/reexec.go b/internal/reexec/reexec.go index af8d347986..7dc6d9222e 100644 --- a/internal/reexec/reexec.go +++ b/internal/reexec/reexec.go @@ -7,6 +7,7 @@ // we require because of the forking limitations of using Go. Handlers can be // registered with a name and the argv 0 of the exec of the binary will be used // to find and execute custom init paths. + package reexec import ( diff --git a/metrics/exp/exp.go b/metrics/exp/exp.go index 5213979aa2..85cabca6b1 100644 --- a/metrics/exp/exp.go +++ b/metrics/exp/exp.go @@ -1,5 +1,6 @@ // Hook go-metrics into expvar // on any /debug/metrics request, load all vars from the registry into expvar, and execute regular expvar handler + package exp import ( diff --git a/metrics/gauge_info.go b/metrics/gauge_info.go index 2f78455649..1862ed55c5 100644 --- a/metrics/gauge_info.go +++ b/metrics/gauge_info.go @@ -39,7 +39,7 @@ func NewRegisteredGaugeInfo(name string, r Registry) *GaugeInfo { return c } -// gaugeInfoSnapshot is a read-only copy of another GaugeInfo. +// GaugeInfoSnapshot is a read-only copy of another GaugeInfo. type GaugeInfoSnapshot GaugeInfoValue // Value returns the value at the time the snapshot was taken. diff --git a/metrics/log.go b/metrics/log.go index 3380bbf9c4..08f3effb81 100644 --- a/metrics/log.go +++ b/metrics/log.go @@ -12,7 +12,7 @@ func Log(r Registry, freq time.Duration, l Logger) { LogScaled(r, freq, time.Nanosecond, l) } -// Output each metric in the given registry periodically using the given +// LogScaled outputs each metric in the given registry periodically using the given // logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos. func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) { du := float64(scale) diff --git a/metrics/metrics.go b/metrics/metrics.go index a9d6623173..c4c43b7576 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -3,6 +3,7 @@ // // // Coda Hale's original work: + package metrics import ( diff --git a/metrics/resetting_timer.go b/metrics/resetting_timer.go index 1b3e87bc3d..66458bdb91 100644 --- a/metrics/resetting_timer.go +++ b/metrics/resetting_timer.go @@ -53,14 +53,14 @@ func (t *ResettingTimer) Snapshot() *ResettingTimerSnapshot { return snapshot } -// Record the duration of the execution of the given function. +// Time records the duration of the execution of the given function. func (t *ResettingTimer) Time(f func()) { ts := time.Now() f() t.Update(time.Since(ts)) } -// Record the duration of an event. +// Update records the duration of an event. func (t *ResettingTimer) Update(d time.Duration) { if !metricsEnabled { return @@ -71,7 +71,7 @@ func (t *ResettingTimer) Update(d time.Duration) { t.sum += int64(d) } -// Record the duration of an event that started at a time and ends now. +// UpdateSince records the duration of an event that started at a time and ends now. func (t *ResettingTimer) UpdateSince(ts time.Time) { t.Update(time.Since(ts)) } diff --git a/metrics/syslog.go b/metrics/syslog.go index 0bc4ed0da5..b265328f87 100644 --- a/metrics/syslog.go +++ b/metrics/syslog.go @@ -9,7 +9,7 @@ import ( "time" ) -// Output each metric in the given registry to syslog periodically using +// Syslog outputs each metric in the given registry to syslog periodically using // the given syslogger. func Syslog(r Registry, d time.Duration, w *syslog.Writer) { for range time.Tick(d) { diff --git a/p2p/discover/v5wire/encoding_test.go b/p2p/discover/v5wire/encoding_test.go index c66a0da9d3..df97e40e89 100644 --- a/p2p/discover/v5wire/encoding_test.go +++ b/p2p/discover/v5wire/encoding_test.go @@ -249,20 +249,20 @@ func TestHandshake_BadHandshakeAttack(t *testing.T) { net.nodeA.expectDecode(t, WhoareyouPacket, whoareyou) // A -> B FINDNODE - incorrect_challenge := &Whoareyou{ + incorrectChallenge := &Whoareyou{ IDNonce: [16]byte{5, 6, 7, 8, 9, 6, 11, 12}, RecordSeq: challenge.RecordSeq, Node: challenge.Node, sent: challenge.sent, } - incorrect_findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, incorrect_challenge, &Findnode{}) - incorrect_findnode2 := make([]byte, len(incorrect_findnode)) - copy(incorrect_findnode2, incorrect_findnode) + incorrectFindNode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, incorrectChallenge, &Findnode{}) + incorrectFindNode2 := make([]byte, len(incorrectFindNode)) + copy(incorrectFindNode2, incorrectFindNode) - net.nodeB.expectDecodeErr(t, errInvalidNonceSig, incorrect_findnode) + net.nodeB.expectDecodeErr(t, errInvalidNonceSig, incorrectFindNode) // Reject new findnode as previous handshake is now deleted. - net.nodeB.expectDecodeErr(t, errUnexpectedHandshake, incorrect_findnode2) + net.nodeB.expectDecodeErr(t, errUnexpectedHandshake, incorrectFindNode2) // The findnode packet is again rejected even with a valid challenge this time. findnode, _ := net.nodeA.encodeWithChallenge(t, net.nodeB, challenge, &Findnode{}) diff --git a/params/protocol_params.go b/params/protocol_params.go index b46e8d66b2..030083aa9a 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -179,7 +179,7 @@ const ( HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935. ) -// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations +// Bls12381MultiExpDiscountTable gas discount table for BLS12-381 G1 and G2 multi exponentiation operations var Bls12381MultiExpDiscountTable = [128]uint64{1200, 888, 764, 641, 594, 547, 500, 453, 438, 423, 408, 394, 379, 364, 349, 334, 330, 326, 322, 318, 314, 310, 306, 302, 298, 294, 289, 285, 281, 277, 273, 269, 268, 266, 265, 263, 262, 260, 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 241, 239, 238, 236, 235, 233, 232, 231, 229, 228, 226, 225, 223, 222, 221, 220, 219, 219, 218, 217, 216, 216, 215, 214, 213, 213, 212, 211, 211, 210, 209, 208, 208, 207, 206, 205, 205, 204, 203, 202, 202, 201, 200, 199, 199, 198, 197, 196, 196, 195, 194, 193, 193, 192, 191, 191, 190, 189, 188, 188, 187, 186, 185, 185, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 176, 176, 175, 174} // Difficulty parameters. diff --git a/signer/core/api.go b/signer/core/api.go index def2d6041f..12acf925f0 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -664,7 +664,7 @@ func (api *SignerAPI) SignGnosisSafeTx(ctx context.Context, signerAddress common return &gnosisTx, nil } -// Returns the external api version. This method does not require user acceptance. Available methods are +// Version returns the external api version. This method does not require user acceptance. Available methods are // available via enumeration anyway, and this info does not contain user-specific data func (api *SignerAPI) Version(ctx context.Context) (string, error) { return ExternalAPIVersion, nil diff --git a/signer/core/uiapi.go b/signer/core/uiapi.go index 43edfe7d97..2f511c7e19 100644 --- a/signer/core/uiapi.go +++ b/signer/core/uiapi.go @@ -48,7 +48,7 @@ func NewUIServerAPI(extapi *SignerAPI) *UIServerAPI { return &UIServerAPI{extapi, extapi.am} } -// List available accounts. As opposed to the external API definition, this method delivers +// ListAccounts lists available accounts. As opposed to the external API definition, this method delivers // the full Account object and not only Address. // Example call // {"jsonrpc":"2.0","method":"clef_listAccounts","params":[], "id":4} From 04a336aee8a911504b2bacc3fb755d726829b235 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 14 Jan 2025 14:42:18 +0100 Subject: [PATCH 16/17] core/types: change SetCodeTx.ChainID to uint256 (#30982) We still need to decide how to handle non-specfic `chainId` in the JSON encoding of authorizations. With `chainId` being a uint64, the previous implementation just used value zero. However, it might actually be more correct to use the value `null` for this case. --- core/blockchain_test.go | 5 ++--- core/state_transition.go | 4 ++-- core/types/gen_authorization.go | 8 ++++---- core/types/transaction_marshalling.go | 16 +++++++++++----- core/types/transaction_signing.go | 2 +- core/types/tx_blob.go | 6 +++--- core/types/tx_dynamic_fee.go | 6 +++--- core/types/tx_setcode.go | 16 ++++++++-------- internal/ethapi/transaction_args.go | 2 +- tests/gen_stauthorization.go | 11 ++++++----- tests/state_test_util.go | 6 +++--- 11 files changed, 44 insertions(+), 38 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index f2a9b953a1..7805a7c6e8 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4265,12 +4265,11 @@ func TestEIP7702(t *testing.T) { // 2. addr1:0xaaaa calls into addr2:0xbbbb // 3. addr2:0xbbbb writes to storage auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{ - ChainID: gspec.Config.ChainID.Uint64(), + ChainID: *uint256.MustFromBig(gspec.Config.ChainID), Address: aa, Nonce: 1, }) auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{ - ChainID: 0, Address: bb, Nonce: 0, }) @@ -4278,7 +4277,7 @@ func TestEIP7702(t *testing.T) { _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { b.SetCoinbase(aa) txdata := &types.SetCodeTx{ - ChainID: gspec.Config.ChainID.Uint64(), + ChainID: uint256.MustFromBig(gspec.Config.ChainID), Nonce: 0, To: addr1, Gas: 500000, diff --git a/core/state_transition.go b/core/state_transition.go index 009b679b27..b6203e6aae 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -529,8 +529,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { // validateAuthorization validates an EIP-7702 authorization against the state. func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { - // Verify chain ID is 0 or equal to current chain ID. - if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID { + // Verify chain ID is null or equal to current chain ID. + if !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 { return authority, ErrAuthorizationWrongChainID } // Limit nonce to 2^64-1 per EIP-2681. diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index be5467c50d..57069cbb1f 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -16,7 +16,7 @@ var _ = (*authorizationMarshaling)(nil) // MarshalJSON marshals as JSON. func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { type SetCodeAuthorization struct { - ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` + ChainID hexutil.U256 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` V hexutil.Uint64 `json:"yParity" gencodec:"required"` @@ -24,7 +24,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { S hexutil.U256 `json:"s" gencodec:"required"` } var enc SetCodeAuthorization - enc.ChainID = hexutil.Uint64(s.ChainID) + enc.ChainID = hexutil.U256(s.ChainID) enc.Address = s.Address enc.Nonce = hexutil.Uint64(s.Nonce) enc.V = hexutil.Uint64(s.V) @@ -36,7 +36,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { type SetCodeAuthorization struct { - ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` + ChainID *hexutil.U256 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` V *hexutil.Uint64 `json:"yParity" gencodec:"required"` @@ -50,7 +50,7 @@ func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' for SetCodeAuthorization") } - s.ChainID = uint64(*dec.ChainID) + s.ChainID = uint256.Int(*dec.ChainID) if dec.Address == nil { return errors.New("missing required field 'address' for SetCodeAuthorization") } diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 993d633c6f..1bbb97a3ec 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -155,7 +155,7 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { enc.Proofs = itx.Sidecar.Proofs } case *SetCodeTx: - enc.ChainID = (*hexutil.Big)(new(big.Int).SetUint64(itx.ChainID)) + enc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig()) enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) enc.To = tx.To() enc.Gas = (*hexutil.Uint64)(&itx.Gas) @@ -353,7 +353,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' in transaction") } - itx.ChainID = uint256.MustFromBig((*big.Int)(dec.ChainID)) + var overflow bool + itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt()) + if overflow { + return errors.New("'chainId' value overflows uint256") + } if dec.Nonce == nil { return errors.New("missing required field 'nonce' in transaction") } @@ -395,7 +399,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.BlobHashes = dec.BlobVersionedHashes // signature R - var overflow bool if dec.R == nil { return errors.New("missing required field 'r' in transaction") } @@ -432,7 +435,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' in transaction") } - itx.ChainID = dec.ChainID.ToInt().Uint64() + var overflow bool + itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt()) + if overflow { + return errors.New("'chainId' value overflows uint256") + } if dec.Nonce == nil { return errors.New("missing required field 'nonce' in transaction") } @@ -470,7 +477,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.AuthList = dec.AuthorizationList // signature R - var overflow bool if dec.R == nil { return errors.New("missing required field 'r' in transaction") } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index d72643b4a8..4d70f37bd3 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -219,7 +219,7 @@ func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big } // Check that chain ID of tx matches the signer. We also accept ID zero here, // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID != 0 && new(big.Int).SetUint64(txdata.ChainID).Cmp(s.chainId) != 0 { + if txdata.ChainID != nil && txdata.ChainID.CmpBig(s.chainId) != 0 { return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) } R, S, _ = decodeSignature(sig) diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index ce1f287caa..88251ab957 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -47,9 +47,9 @@ type BlobTx struct { Sidecar *BlobTxSidecar `rlp:"-"` // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + V *uint256.Int + R *uint256.Int + S *uint256.Int } // BlobTxSidecar contains the blobs of a blob transaction. diff --git a/core/types/tx_dynamic_fee.go b/core/types/tx_dynamic_fee.go index 8b5b514fde..981755cf70 100644 --- a/core/types/tx_dynamic_fee.go +++ b/core/types/tx_dynamic_fee.go @@ -37,9 +37,9 @@ type DynamicFeeTx struct { AccessList AccessList // Signature values - V *big.Int `json:"v" gencodec:"required"` - R *big.Int `json:"r" gencodec:"required"` - S *big.Int `json:"s" gencodec:"required"` + V *big.Int + R *big.Int + S *big.Int } // copy creates a deep copy of the transaction data and initializes all fields. diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index f14ae3bc9d..0fb5362c26 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -49,7 +49,7 @@ func AddressToDelegation(addr common.Address) []byte { // SetCodeTx implements the EIP-7702 transaction type which temporarily installs // the code at the signer's address. type SetCodeTx struct { - ChainID uint64 + ChainID *uint256.Int Nonce uint64 GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas GasFeeCap *uint256.Int // a.k.a. maxFeePerGas @@ -61,16 +61,16 @@ type SetCodeTx struct { AuthList []SetCodeAuthorization // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + V *uint256.Int + R *uint256.Int + S *uint256.Int } //go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go // SetCodeAuthorization is an authorization from an account to deploy code at its address. type SetCodeAuthorization struct { - ChainID uint64 `json:"chainId" gencodec:"required"` + ChainID uint256.Int `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` V uint8 `json:"yParity" gencodec:"required"` @@ -80,7 +80,7 @@ type SetCodeAuthorization struct { // field type overrides for gencodec type authorizationMarshaling struct { - ChainID hexutil.Uint64 + ChainID hexutil.U256 Nonce hexutil.Uint64 V hexutil.Uint64 R hexutil.U256 @@ -180,7 +180,7 @@ func (tx *SetCodeTx) copy() TxData { // accessors for innerTx. func (tx *SetCodeTx) txType() byte { return SetCodeTxType } -func (tx *SetCodeTx) chainID() *big.Int { return big.NewInt(int64(tx.ChainID)) } +func (tx *SetCodeTx) chainID() *big.Int { return tx.ChainID.ToBig() } func (tx *SetCodeTx) accessList() AccessList { return tx.AccessList } func (tx *SetCodeTx) data() []byte { return tx.Data } func (tx *SetCodeTx) gas() uint64 { return tx.Gas } @@ -207,7 +207,7 @@ func (tx *SetCodeTx) rawSignatureValues() (v, r, s *big.Int) { } func (tx *SetCodeTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.ChainID = chainID.Uint64() + tx.ChainID = uint256.MustFromBig(chainID) tx.V.SetFromBig(v) tx.R.SetFromBig(r) tx.S.SetFromBig(s) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index a39a6666f4..175ac13a0f 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -503,7 +503,7 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { } data = &types.SetCodeTx{ To: *args.To, - ChainID: args.ChainID.ToInt().Uint64(), + ChainID: uint256.MustFromBig(args.ChainID.ToInt()), Nonce: uint64(*args.Nonce), Gas: uint64(*args.Gas), GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)), diff --git a/tests/gen_stauthorization.go b/tests/gen_stauthorization.go index fbafd6fdea..4f2c50bd9f 100644 --- a/tests/gen_stauthorization.go +++ b/tests/gen_stauthorization.go @@ -16,7 +16,7 @@ var _ = (*stAuthorizationMarshaling)(nil) // MarshalJSON marshals as JSON. func (s stAuthorization) MarshalJSON() ([]byte, error) { type stAuthorization struct { - ChainID math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce math.HexOrDecimal64 `json:"nonce" gencodec:"required"` V math.HexOrDecimal64 `json:"v" gencodec:"required"` @@ -24,7 +24,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) { S *math.HexOrDecimal256 `json:"s" gencodec:"required"` } var enc stAuthorization - enc.ChainID = math.HexOrDecimal64(s.ChainID) + enc.ChainID = (*math.HexOrDecimal256)(s.ChainID) enc.Address = s.Address enc.Nonce = math.HexOrDecimal64(s.Nonce) enc.V = math.HexOrDecimal64(s.V) @@ -36,7 +36,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *stAuthorization) UnmarshalJSON(input []byte) error { type stAuthorization struct { - ChainID *math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *math.HexOrDecimal64 `json:"nonce" gencodec:"required"` V *math.HexOrDecimal64 `json:"v" gencodec:"required"` @@ -47,9 +47,10 @@ func (s *stAuthorization) UnmarshalJSON(input []byte) error { if err := json.Unmarshal(input, &dec); err != nil { return err } - if dec.ChainID != nil { - s.ChainID = uint64(*dec.ChainID) + if dec.ChainID == nil { + return errors.New("missing required field 'chainId' for stAuthorization") } + s.ChainID = (*big.Int)(dec.ChainID) if dec.Address == nil { return errors.New("missing required field 'address' for stAuthorization") } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 6e66bbaa72..740ebd4afd 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -140,7 +140,7 @@ type stTransactionMarshaling struct { // Authorization is an authorization from an account to deploy code at it's address. type stAuthorization struct { - ChainID uint64 + ChainID *big.Int `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` V uint8 `json:"v" gencodec:"required"` @@ -150,7 +150,7 @@ type stAuthorization struct { // field type overrides for gencodec type stAuthorizationMarshaling struct { - ChainID math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 Nonce math.HexOrDecimal64 V math.HexOrDecimal64 R *math.HexOrDecimal256 @@ -446,7 +446,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList)) for i, auth := range tx.AuthorizationList { authList[i] = types.SetCodeAuthorization{ - ChainID: auth.ChainID, + ChainID: *uint256.MustFromBig(auth.ChainID), Address: auth.Address, Nonce: auth.Nonce, V: auth.V, From 8dfad579e961f4fdd718fdcf435ad68f4d6d67df Mon Sep 17 00:00:00 2001 From: jwasinger Date: Tue, 14 Jan 2025 23:26:24 +0800 Subject: [PATCH 17/17] eth/gasprice: ensure cache purging goroutine terminates with subscription (#31025) --- eth/gasprice/gasprice.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index fe2e4d408a..4fd3df7428 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -120,16 +120,23 @@ func NewOracle(backend OracleBackend, params Config, startPrice *big.Int) *Oracl cache := lru.NewCache[cacheKey, processedFees](2048) headEvent := make(chan core.ChainHeadEvent, 1) - backend.SubscribeChainHeadEvent(headEvent) - go func() { - var lastHead common.Hash - for ev := range headEvent { - if ev.Header.ParentHash != lastHead { - cache.Purge() + sub := backend.SubscribeChainHeadEvent(headEvent) + if sub != nil { // the gasprice testBackend doesn't support subscribing to head events + go func() { + var lastHead common.Hash + for { + select { + case ev := <-headEvent: + if ev.Header.ParentHash != lastHead { + cache.Purge() + } + lastHead = ev.Header.Hash() + case <-sub.Err(): + return + } } - lastHead = ev.Header.Hash() - } - }() + }() + } return &Oracle{ backend: backend,