core, core/state, core/vm: merge geth v1.17.3 part 2 (v1.17.4 sync, milestone 5/6) - #2342
Conversation
Co-authored-by: Felix Lange <fjl@twurst.com>
This PR fixes ethereum/go-ethereum#34623 by changing the `vm.StateDB` interface: Instead of `EmitLogsForBurnAccounts()` emitting burn logs, `LogsForBurnAccounts() []*types.Log` just returns these logs which are then emitted by the caller. This way when tracing is used, `hookedStateDB.AddLog` will be used automatically and there is no need to duplicate either the burn log logic or the `OnLog` tracing hook.
This is to fix a crasher in keeper.
This tool is designed for the offline translation of an MPT database to a binary trie. This is to be used for users who e.g. want to prove equivalence of a binary tree chain shadowing the MPT chain. It adds a `bintrie` command, cleanly separating the concerns.
already check on line 40 before.
`BinaryTrie.DeleteAccount` was a no-op, silently ignoring the caller's deletion request and leaving the old `BasicData` and `CodeHash` in the trie. Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
…before returning values (#34690) Fix `GetAccount` returning **wrong account data** for non-existent addresses when the trie root is a `StemNode` (single-account trie) — the `StemNode` branch returned `r.Values` without verifying the queried address's stem matches. Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Pre-refactor PR to get 8037 upstreamed in chunks --------- Co-authored-by: Gary Rong <garyrong0905@gmail.com>
The spec has been changed during SIC #49, the offset is encoded as a big-endian number.
Two fixes for `testing_buildBlockV1`: 1. Add `omitempty` to `SlotNumber` in `ExecutableData` so it is omitted for pre-Amsterdam payloads. The spec defines the response as `ExecutionPayloadV3` which does not include `slotNumber`. 2. Pass `res.fees` instead of `new(big.Int)` in `BuildTestingPayload` so `blockValue` reflects actual priority fees instead of always being zero. Corresponding fixture update: ethereum/execution-apis#783
The comment formula showed (i+3) but the code multiplies by 9 (Lsh 3 + add = 8+1). This was a error when porting from upstream golang.org/x/crypto/bn256 where ξ=i+3. Go-ethereum changed the constant to ξ=i+9 but forgot to update the inner formula.
TestUpdatedKeyfileContents was intermittently failing with: - Emptying account file failed - wasn't notified of new accounts Root cause: waitForAccounts required the account list match and an immediately readable ks.changes notification in the same instant, creating a timing race between cache update visibility and channel delivery. This change keeps the same timeout window but waits until both conditions are observed, which preserves test intent while removing the flaky timing dependency. Validation: - go test ./accounts/keystore -run '^TestUpdatedKeyfileContents$' -count=100
Return ErrInvalidOpCode with the executing opcode and offending immediate for forbidden DUPN, SWAPN, and EXCHANGE operands. Extend TestEIP8024_Execution to assert both opcode and operand for all invalid-immediate paths.
# Summary
Replaces the inline `errors.New("event signature mismatch")` in
generated `UnpackXxxEvent` methods with per-event package-level sentinel
errors (e.g. `ErrTransferSignatureMismatch`,
`ErrApprovalSignatureMismatch`), allowing callers to reliably
distinguish a topic mismatch from a genuine decoding failure via
`errors.Is`.
Each event gets its own sentinel, generated via the abigen template:
```go
var ErrTransferSignatureMismatch = errors.New("event signature mismatch")
```
This scoping is intentional — it allows callers to be precise about
*which* event was mismatched, which is useful when routing logs across
multiple unpackers.
# Motivation
Previously, all errors returned from `UnpackXxxEvent` were
indistinguishable without string matching. This is especially
problematic when processing logs sourced from `eth_getBlockReceipts`,
where a caller receives the full set of logs for a block across all
contracts and event types. In that context, a signature mismatch is
expected and should be skipped, while any other error (malformed data,
topic parsing failure) indicates something is genuinely wrong and should
halt execution:
```go
for _, log := range blockLogs {
event, err := contract.UnpackTransferEvent(log)
if errors.Is(err, gen.ErrTransferSignatureMismatch) {
continue // not our event, expected
}
if err != nil {
return fmt.Errorf("unexpected decode failure: %w", err) // alert
}
// process event
}
```
**Changes:**
- `abigen` template: generates a `ErrXxxSignatureMismatch` sentinel per
event and returns it on topic mismatch instead of an inline error
- Existing generated bindings & testdata: regenerated to reflect the
update
Implements #34075
This fixes a truncation bug that results in an invalid serialization of
empty EIP712.
For example:
```json
{
"method": "eth_signTypedData_v4",
"request": {
"types": {
"EIP712Domain": [
{
"name": "version",
"type": "string"
}
],
"Empty": []
},
"primaryType": "Empty",
"domain": {
"version": "0"
},
"message": {}
}
}
```
When calculating the type-hash for the stuct-hash, it will incorrectly
use `Empty)` instead of `Empty()`
runtime.setDefaults was unconditionally assigning cfg.Random =
&common.Hash{}, which silently overwrote any caller-provided Random
value. This made it impossible to simulate a specific PREVRANDAO and
also forced post-merge rules whenever London was active, regardless of
the intended environment.
This change only initializes cfg.Random when it is nil, matching how
other fields in Config are defaulted. Existing callers that did not set
Random keep the same behavior (a non-nil zero hash still enables
post-merge semantics), while callers that explicitly set Random now get
their value respected.
Fixes #34108 The UDPv5 test harness (`newUDPV5Test`) uses the default `PingInterval` of 3 seconds. When tests like `TestUDPv5_findnodeHandling` insert nodes into the routing table via `fillTable`, the table's revalidation loop may schedule PING packets for those nodes. Under the race detector or on slow CI runners, the test runs long enough for revalidation to fire, causing background pings to be written to the test pipe. The `close()` method then finds these as unmatched packets and fails. The fix sets `PingInterval` to a very large value in the test harness so revalidation never fires during tests. Verified locally: 100 iterations with `-race -count=100` pass reliably, where previously the test would fail within ~50 iterations.
… (#34043) This fixes the remaining Hive discv5/FindnodeResults failures in the cmd/devp2p/internal/v5test fixture. The issue was in the simulator-side bystander behavior, not in production discovery logic. The existing fixture could get bystanders inserted into the remote table, but under current geth behavior they were not stable enough to remain valid FINDNODE results. In particular, the fixture still had a few protocol/behavior mismatches: - incomplete WHOAREYOU recovery - replies not consistently following the UDP envelope source - incorrect endpoint echoing in PONG - fixture-originated PING using the wrong ENR sequence - bystanders answering background FINDNODE with empty NODES That last point was important because current lookup accounting can treat repeatedly unhelpful FINDNODE interactions as failures. As a result, a bystander could become live via PING/PONG and still later be dropped from the table before the final FindnodeResults assertion. This change updates the fixture so that bystanders behave more like stable discv5 peers: - perform one explicit initial handshake, then switch to passive response handling - resend the exact challenged packet when handling WHOAREYOU - reply to the actual UDP packet source and mirror that source in PONG.ToIP / PONG.ToPort - use the bystander’s own ENR sequence in fixture-originated PING - prefill each bystander with the bystander ENR set and answer FINDNODE from that set The result is that the fixture now forms a small self-consistent lookup environment instead of a set of peers that are live but systematically poor lookup participants.
This is meant to be run daily, in order to verify the FreeBSD build wasn't broken like last time.
Adds config to add Prague prune point for the hoodi testnet.
Optimizes the transient storage. Turns it from a map of maps into a single map keyed by <account,slot>.
This PR simplifies the implementation of EIP-7610 by eliminating the
need to check storage emptiness during contract deployment.
EIP-7610 specifies that contract creation must be rejected if the
destination account has a non-zero nonce, non-empty runtime code, or
**non-empty storage**.
After EIP-161, all newly deployed contracts are initialized with a nonce
of one. As a result, such accounts are no longer eligible as deployment
targets unless they are explicitly cleared.
However, prior to EIP-161, contracts were initialized with a nonce of
zero. This made it possible to end up with accounts that have:
- zero nonce
- empty runtime code
- non-empty storage (created during constructor execution)
- non-zero balance
These edge-case accounts complicate the storage emptiness check.
In practice, contract addresses are derived using one of the following
formulas:
- `Keccak256(rlp({sender, nonce}))[12:]`
- `Keccak256([]byte{0xff}, sender, salt[:], initHash)[12:]`
As such, an existing address is not selected as a deployment target
unless a collision occurs, which is extremely unlikely.
---
Previously, verifying storage emptiness relied on GetStorageRoot.
However, with the transition to the block-based access list (BAL),
the storage root is no longer available, as computing it would require
reconstructing the full storage trie from all mutations of preceding
transactions.
To address this, this PR introduces a simplified approach: it hardcodes
the set of known accounts that have zero nonce, empty runtime code,
but non-empty storage and non-zero balance. During contract deployment,
if the destination address belongs to this set, the deployment is
rejected.
This check is applied retroactively back to genesis. Since no address
collision events have occurred in Ethereum’s history, this change does
not
alter existing behavior. Instead, it serves as a safeguard for future
state
transitions.
… `testing_buildBlockV1` (#34722) This is a copy of #34721 but against `master` (rather than `bal-devnet-3`), as requested by @jwasinger, since the slotnum logic now exists on `master` as well.
…y (#34723) StateDB.Commit first commits all storage changes into the storage trie, then updates the account metadata with the new storage root into the account trie. Within StateDB.Commit, the new storage trie root has already been computed and applied as the storage root. This PR explicitly skips the redundant storage trie root assignment for readability.
Auto-enable logic for `StatelessSelfValidation` was reading CLI flag directly via `ctx.Bool()`, bypassing the merged `cfg.EnableWitnessStats` value. Now uses `cfg.EnableWitnessStats` so config file settings trigger the same auto-enable behavior as CLI flags.
Changes the log handler to check for vmodule level overrides even for messages above the current level. This enables the user to selectively hide messages from certain packages, among other things. Also fixes a bug where handler instances created by WithAttr would not follow the level setting anymore. The WithAttrs method is calledd by slog.Logger.With, which we also use in go-ethereum to create context specific loggers with pre-filled attributes. Under the previous implementation of WithAttrs, if the application created a long-lived logger (for example, for a specific peer), then that logger would not be affected by later level changes done on the top-level logger, leading to potentially missed events. Closes: #30717 --------- Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de> Co-authored-by: Felix Lange <fjl@twurst.com>
`trace.noreturndata` is documented as "enable return data output" but the flag name/value imply it disables return data. This is confusing for users and likely inverted wording. Update the Usage string to reflect the actual behavior (disable return data output).
Pre-cascade ahead of milestone 5 part 2 (#2342), run while #2341 is in review. Seventy-four commits. One conflict, in core/stateless/encoding.go. The auto-merge had already combined the bodies correctly; only the import block actually conflicted, because each side had added a different import for its own change. Both changes are wanted and both are kept: - the base contributes WIT2's lexicographic sort of state entries in EncodeRLP, which is load-bearing rather than cosmetic -- the WIT2 BP-signed witness hash is computed independently by the producer and by every verifier and has to match byte for byte, and Go's randomized map iteration would otherwise encode the same witness differently on each call. It also contributes the corrected note that contract bytecodes are not in the wire format, verifiers read them through CodeRoutingDB. - this branch contributes upstream's #34683 empty-witness check in FromExtWitness, rejecting a witness carrying no headers. Resolution approved by the operator rather than taken autonomously, witness encoding being a deliberate Bor divergence. Checked before asking: NewWitness can build a header-less witness only when its chain argument is nil, and all three production call sites in core/blockchain.go pass a real chain, so the new rejection is unreachable from the live path. Verified beyond the usual gates, since -short skips every test that touches this code: witness regeneration green non-short -- AllBlocks, PipelinedSRCAllBlocks, and PipelinedSRCChained at 222 of 222 mainnet pairs with no skips, which is the test that exercises exactly the producer/consumer byte-identity the sort exists to protect. Build clean, every test package compiles, vet and gofmt clean, full suite 144 packages 0 failures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eleven AI review comments across three PRs, ten distinct findings, four cascades. The commits carry what changed; this carries the reasoning a release reader cannot recover from a diff. Kept in one place rather than split across the four branches. ledger.md exists on each of them and editing it in four places is what produced the only real conflict in the #2341 cascade; this branch merges last, so one entry lands the record exactly once. The table records provenance beside each finding, because that is what decided most of them: on a merge PR the majority of what gets flagged is upstream's own code arriving verbatim, and diffing the file against the upstream commit settles it faster than reasoning about the code. Six of nine on #2337 and two of three on #2340 went that way. Three findings were upstream's and still fixed, which needs the rule stated rather than left implicit: fix when the repair changes nothing a peer or caller can observe, record when it would change wire behaviour or a converged file's bytes. That is why the eth/70 deadlock and the missing lookup bound were fixed while the dump.go short-prefix change was only recorded. Also keeps the two verification lessons this cycle cost time to learn: go build does not compile test files, so it passed on a cascade that failed to build eight call sites; and -short skips every witness test, so a green suite proved nothing about the #2342 witness resolution until the regeneration tests were run non-short. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
|
@claude review |
|
codegenie review |
|
🧞 Codegenie review failed (
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved moderate findings remain in snapshot discovery, EIP-7610 chain-ID handling, tracer diff output, and fixture filtering.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 3
Open (3)
What changed in this PR
This PR continues the Bor synchronization with go-ethereum v1.17.3 batches 21–22, updating VM gas handling, trie/state behavior, tooling, tests, and CI.
Changes:
- Migrates VM gas functions to
GasCosts. - Updates binary-trie, pathdb, state logging, tracers, and EIP-7610 tooling.
- Refreshes tests, generated bindings, utilities, and FreeBSD CI.
| File | Change |
|---|---|
triedb/pathdb/reader.go |
Corrects pathdb error text. |
triedb/pathdb/lookup.go |
Adds explicit lookup status. |
triedb/pathdb/layertree.go |
Handles zero-valued layer roots safely. |
triedb/pathdb/layertree_test.go |
Adds zero-root fallback coverage. |
trie/bintrie/trie.go |
Updates account reads and deletion; comment typo remains. |
trie/bintrie/stem_node.go |
Adds stem reads and dirty tracking. |
trie/bintrie/stem_node_test.go |
Tests stem reads and flushing. |
trie/bintrie/key_encoding.go |
Updates binary-trie key encoding. |
trie/bintrie/internal_node.go |
Adds internal-node dirty tracking. |
trie/bintrie/internal_node_test.go |
Tests dirty subtree flushing. |
trie/bintrie/empty.go |
Marks new stems dirty. |
trie/bintrie/empty_test.go |
Tests dirty initialization. |
trie/bintrie/binary_node.go |
Preserves dirty state during deserialization. |
tests/state_test.go |
Adds incompatible-fixture skips; scope and documentation need correction. |
tests/state_test_util.go |
Fixes invalid-EIP error reporting. |
tests/block_test.go |
Adds incompatible-fixture skips; scope and documentation need correction. |
signer/core/apitypes/types.go |
Handles empty type dependencies. |
p2p/discover/v5_udp_test.go |
Disables periodic test revalidation. |
log/logger_test.go |
Tests dynamic logging configuration. |
log/handler_glog.go |
Refactors concurrent logging configuration. |
eth/tracers/native/prestate.go |
Preserves explicit code clearing; code-hash normalization needs correction. |
eth/tracers/native/gen_account_json.go |
Updates account JSON types. |
eth/tracers/js/tracer_test.go |
Adapts tests to vector gas. |
docs/upstream-merges/v1.17.4/ledger.md |
Records upstream merge decisions. |
crypto/bn256/google/gfp2.go |
Corrects multiplication documentation. |
core/vm/runtime/runtime.go |
Preserves configured randomness. |
core/vm/runtime/runtime_test.go |
Tests runtime randomness defaults. |
core/vm/operations_verkle.go |
Migrates Verkle gas functions. |
core/vm/operations_acl.go |
Migrates ACL gas functions. |
core/vm/jump_table.go |
Changes gas-function signatures. |
core/vm/interpreter.go |
Deducts regular gas from vectors. |
core/vm/interpreter_dispatch.go |
Updates generated dispatch gas handling. |
core/vm/interface.go |
Updates the state database interface. |
core/vm/instructions.go |
Adapts gas and invalid-opcode handling. |
core/vm/instructions_test.go |
Extends opcode and gas tests. |
core/vm/gen_dispatch/main.go |
Updates dispatch generation. |
core/vm/gascosts.go |
Adds gas-vector types and helpers. |
core/vm/evm.go |
Adopts EIP-7610 and vector gas. |
core/vm/errors.go |
Adds invalid-opcode operands. |
core/vm/eips.go |
Updates EIP-4762 gas access. |
core/vm/eip7610.go |
Adds EIP-7610 filtering; chain-ID lookup must be exact and nil-safe. |
core/vm/eip7610_test.go |
Tests EIP-7610 account data. |
core/vm/contracts_test.go |
Adapts gas assertions. |
core/vm/contract.go |
Stores contract gas vectors. |
core/types/tx_legacy.go |
Corrects panic text. |
core/stateless/encoding.go |
Rejects headerless witnesses. |
core/state/trie_prefetcher_test.go |
Adapts binary-trie prefetch tests. |
core/state/transient_storage.go |
Flattens transient-storage keys. |
core/state/statedb.go |
Refactors burn-log generation and commits. |
core/state/statedb_test.go |
Updates state and binary-trie tests. |
core/state/statedb_hooked.go |
Forwards returned burn logs. |
core/state/state_object.go |
Avoids redundant trie-root updates. |
core/state/parallel_statedb.go |
Returns ordered burn logs. |
core/state/database.go |
Supports binary-trie copying. |
core/state_transition.go |
Adds returned burn logs to state logs. |
core/rawdb/freezer_utils.go |
Improves freezer durability and cleanup. |
core/rawdb/freezer_table.go |
Closes files on initialization errors. |
core/history/historymode.go |
Adds Hoodi prune metadata. |
core/genesis_test.go |
Updates the binary-trie genesis root. |
core/filtermaps/math_test.go |
Simplifies match validation. |
cmd/utils/flags.go |
Enables stateless validation from configuration. |
cmd/geth/snapshot.go |
Adds EIP-7610 account discovery; nil handling, iterator cleanup/error checks, and failed-preimage propagation need correction. |
cmd/geth/main.go |
Registers binary-trie commands. |
cmd/geth/dbcmd.go |
Adds code-data export. |
cmd/geth/bintrie_convert.go |
Adds MPT-to-binary-trie conversion. |
cmd/geth/bintrie_convert_test.go |
Tests binary-trie conversion. |
cmd/evm/runner.go |
Compares errors by content. |
cmd/evm/main.go |
Corrects CLI flag text. |
cmd/devp2p/internal/v5test/framework.go |
Replies to observed UDP endpoints. |
cmd/devp2p/internal/v5test/discv5tests.go |
Stabilizes discovery tests. |
build/checksums.txt |
Updates Go toolchain checksums. |
beacon/engine/types.go |
Makes slot numbers optional in JSON. |
beacon/engine/gen_ed.go |
Regenerates executable-data JSON. |
accounts/keystore/account_cache_test.go |
Improves watcher synchronization. |
accounts/abi/bind/v2/lib_test.go |
Uses exported event errors. |
accounts/abi/bind/v2/internal/contracts/events/bindings.go |
Uses typed event errors. |
accounts/abi/bind/v2/internal/contracts/db/bindings.go |
Uses typed event errors. |
accounts/abi/bind/v2/base.go |
Exports event-signature errors. |
accounts/abi/abigen/testdata/v2/tuple.go.txt |
Updates generated tuple bindings. |
accounts/abi/abigen/testdata/v2/token.go.txt |
Updates generated token bindings. |
accounts/abi/abigen/testdata/v2/overload.go.txt |
Updates generated overload bindings. |
accounts/abi/abigen/testdata/v2/numericmethodname.go.txt |
Updates generated bindings. |
accounts/abi/abigen/testdata/v2/nameconflict.go.txt |
Updates generated bindings. |
accounts/abi/abigen/testdata/v2/eventchecker.go.txt |
Updates generated event bindings. |
accounts/abi/abigen/testdata/v2/dao.go.txt |
Updates generated DAO bindings. |
accounts/abi/abigen/testdata/v2/crowdsale.go.txt |
Updates generated crowdsale bindings. |
accounts/abi/abigen/source2.go.tpl |
Updates the binding generator template. |
.github/workflows/freebsd.yml |
Adds FreeBSD CI coverage. |
Files not reviewed (1)
- beacon/engine/gen_ed.go: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…edger The #2341 deadlock row now points at a2a83b9, which replaced b246fba's fix with upstream #35537 after review found the earlier fix opened a continuation/cancel window. Adds the #2341 envelope-size row and the four #2342 AI findings, and corrects the section's comment counts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings #2341's eth/69 receipts test and develop's OpenTelemetry 1.45 bump and nightly govulncheck Slack step onto this branch. No conflicts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
cd9097f
into
upstream-merge-v1.17.4

Important
Reviewer guide — stacked PR 8 of 12. Part of the combined go-ethereum v1.17.4 + v1.17.5 upstream sync, which ships as one stable release. Every PR in the stack merges into the base branch
upstream-merge-v1.17.4; that base merges intodeveloponce, at the very end — not per-PR.Merge-commit only — never squash. Squashing rewrites a branch's SHAs and breaks every PR stacked above it.
Review bottom-up: #2308, #2319, #2325, #2328, #2337, #2340 and #2341 have merged into the base. The open stack is #2342 → #2343 → #2345 → #2346 → #2354. This PR is now the bottom of the stack and targets the base directly.
Expected-red / flaky checks (not code blockers):
Quality metrics(diffguard — skipped by team decision; it also mis-scopes across a stacked diff, comparing against the bottom of the stack), andcodecov/patch(below the 90% target on a diff that is mostly upstream code carried in verbatim;codecov/projectis green here). The other 17 checks pass. Kurtosis e2e occasionally flakes (~1-in-5, devtools-owned) and is re-run by hand. Full per-batch conflict-resolution reasoning is indocs/upstream-merges/.Summary
Merges go-ethereum up to
5af5510b1— batches 2 and 3 of 7 for the v1.17.3milestone of the ongoing v1.17.4 upstream sync. 40 upstream first-parent commits,
46 conflicts, 89 files, +2998/−743.
This is part 2 of the v1.17.3 milestone, stacked on the eth/70 adoption
(#2341). Batches 24–26 and the milestone doc chores land in a part 3 on top of
the
CachingDBsplit adoption described below, for the same reason part 1 wassplit: keep each PR either purely an upstream merge or purely hand-written Bor
code, never both.
c453b99a55af5510b1Where the Bor changes actually are
90 files, but most need no scrutiny. Measured by diffing this PR's patch against
upstream's own patch over
04e40995d..5af5510b1, rather than from theresolution notes:
5af5510b1— skim, don't auditThe Bor-carrying files worth reading, and what to check:
core/vm/operations_acl.goGasCostsvector, so Bor's PIP-88 twins had to be converted alongside upstream's:makeGasSStoreFuncPIP88andgasSLoadPIP88have no upstream counterpart, and their sentry and Hampi-gate comparisons now readcontract.Gas.RegularGas. Check the right vector field is used in each, and that the Hampi gate still compares the same quantity it did before. A missed conversion would not compile, so the risk is a wrong field, not a missing one.core/vm/interpreter_dispatch.go,core/vm/gen_dispatch/main.gocore/state/parallel_statedb.goEmitLogsForBurnAccounts→LogsForBurnAccountsrework, which now returns logs rather than appending them so the caller controls ordering. This is the POS-3716 surface — the EIP-7708 burn-log path where serial and V2 already diverge at enable time. Check the refactor does not change that divergence, in either direction. Amsterdam is dormant, so nothing is live today.core/state/statedb_test.gocore/state/database.goCachingDBsplit is deferred to its own PR — see the deferral section below. This is the bulk of what this PR does not take.triedb/pathdb/layertree_test.gocmd/geth/bintrie_convert.go,snapshot.go,core/history/historymode.gocore/vm/contracts_test.godocs/upstream-merges/v1.17.4/ledger.mdConsensus surface: EIP-7610 reworked (#34718) — adopted, no-op for Bor
eb67d6193removes the storage-emptiness check from contract creation — withblock-level access lists the storage root is no longer available at creation time
— and replaces it with a hardcoded per-chain set of accounts eligible for
rejection (
core/vm/eip7610.go, new). This changes contract-creation rejectionsemantics, so it gets an argument rather than a shrug. It is a no-op for Bor,
provably:
isEIP7610RejectedAccountis keyed on chain ID and returns false for chainsabsent from the map. Bor's chains (137, 80002) are absent.
genesis need an entry, because the pathological account class — zero nonce,
empty code, non-empty storage — can only be produced by pre-EIP-158 creation
semantics. Bor mainnet and Amoy both set
EIP158Block: 0, against Ethereummainnet's 2,675,000. That is exactly why upstream needs a 28-address list and
Bor needs none.
Residual, recorded rather than hand-waved: a Bor genesis-alloc account with
storage, empty code and zero nonce would previously have been rejected as a
deployment target and now would not. Reaching it requires a keccak address
collision, which is upstream's own stated basis for the change. Upstream shipped
geth snapshot list-eip7610-eligible-accountsin the same commit, so this isanswerable against a live database if we want certainty.
coreturns gas into a vector (#34691)633385516changesContract.Gasfromuint64toGasCosts{RegularGas, StateGas}and makes everygasFuncreturnGasCosts.StateGasis unused — it is upstream's pre-refactor for EIP-8037, which landslater in this sync. Ten of batch 21's twelve conflicts were files whose only
divergence from upstream was a blank line before a
return.The real work was four Bor mirrors of the changed type, none of which raised a
conflict — they surface only at build time, or not at all:
makeGasSStoreFuncPIP88andgasSLoadPIP88kept(uint64, error)while theirupstream siblings auto-merged. Mirrored exactly what upstream did to the
siblings, nothing more.
core/vm/interpreter_dispatch.gois generated, and itsrunSwitchmirrorsupstream's
Run()loop including the gas deduction. Fixed the generator(
core/vm/gen_dispatch/main.go) and rango generate ./core/vm/per thatpackage's own documented upstream-merge procedure; the output was never
hand-edited.
ParallelStateDB.EmitLogsForBurnAccounts→LogsForBurnAccounts() []*types.Log(#34688, an EIP-7708 tracer-ordering fix). Bor's mirror keeps itsaddress sort, which is what holds V1/V2 log order identical. The call site is
IsAmsterdam-gated, so dormant.One feature deferred, and it is scheduled
#34700 —
CachingDBsplit intoMerkleDB+UBTDB. 31 of batch 22's 34conflicts. It also renames the Verkle vocabulary to UBT. Upstream states it is
prerequisite groundwork for #34004, the UBT state transition — which is not in
this sync's range at all; the only reference to it anywhere in the fetched
history is #34700's own commit message.
Deferred out of this merge so a hand-written restructure of consensus-critical
core/statedoes not ride inside a 20-commit merge commit, and adopted on itsown branch immediately, before batch 23 — because the sequel is in the very
next batch: #34763 applies the same split to
core/state/reader.go, the filecarrying Bor's prefetch-attribution instrumentation, and #34843 follows later.
Declining the family would fork
core/stateon its primary type name for therest of the sync.
The revert was not applied blindly. Nine files in #34700's 67-file footprint
are also touched by other in-range commits, so a wholesale revert would have
silently discarded adopted work — the
core/blockchain_reader.gomistake frompart 1. Each was reverted to Bor HEAD and then had the other commits re-applied
in upstream chronological order:
cmd/utils/flags.go,core/state/database.go,state_object.go,statedb.go,statedb_test.go,trie_prefetcher_test.go,core/vm/evm.go,tests/state_test_util.go,triedb/pathdb/reader.go.Other resolutions worth a look
params/config.go(16 hunks, #34700) — kept Bor's side throughout. Borreplaced timestamp fork scheduling with block-based fields and deleted the
timestamp fields, so upstream's
VerkleTime→UBTTimerename targets fields Bordoes not have. Verified the upstream diff for this file contains only that
rename, so take-ours discards nothing.
core/state/transient_storage.go(#33695) — took upstream's flattening ofmap[Address]Storageintomap[transientStorageKey]Hash, after confirmingBor's divergence in the file was blank-line-only and Bor's only consumers
(
ParallelStateDB) are representation-agnostic. This made Bor's ownEqualTStest helper redundant and uncompilable; removed in favour of
maps.Equal.eth/filters/filter.go(#33163) — kept Bor's deletion of the range-limitcheck, after verifying that Bor enforces it one layer up in
api.go(
checkBlockRangeLimit, covering botheth_getLogsandbor_getLogs). Theempty side drops no DoS guard.
core/history/historymode.go(#34714) — added the hoodi Prague prune point toBor's restructured prune-point maps. Inert for Bor's own networks.
cmd/geth/snapshot.goandcmd/geth/bintrie_convert.go— new upstream callersof
MakeChainDatabase, which in Bor carries an extradisableFreezeparameter. Two occurrences across two batches, no conflict either time,
caught at build. Every future upstream caller will break the same way until the
signature converges; recorded as a standing watch item.
eth/catalyst/api_testing.go(#34722) — kept Bor's deletion; the file wentwith
testing_buildBlockV1(#33656, declined in batch 12). Third orphanedchange on that declined feature, after #34094 and #34704.
eth/tracers/.../eip7702_deauth.json(#34675) — adopted the prestate codehashfix, removed its new fixture. The fixture configures forks by timestamp, which
Bor's block-based
ChainConfigsilently drops on unmarshal, leaving noblob-capable fork; its non-nil
excessBlobGasthen panicsCalcBlobFee. Sameroot cause as part 1's
tests/init.go, and it predicts every future upstreamfixture pairing timestamp forks with blob fields. The durable fix is to teach
the fixture loaders to map
*Timefork keys onto Bor's*Blockfields once,centrally.
Full per-file reasoning is in
docs/upstream-merges/v1.17.4/ledger.md. The docupdates for both batches are written but ride in the milestone chores commit in
part 3, so this PR carries no doc changes.
Cascade
From the base after #2341 merged (
b0977336c), no conflicts. Brings #2341'slast commit (an eth/69 receipts test) and
develop's merge into the base(OpenTelemetry 1.44 → 1.45 in
go.mod/go.sum, and the nightly govulncheckSlack step). After the merge:
go build ./...clean,go mod tidyno diff,every test package compiles (
go test -run XXXNOMATCHXXX ./...), andeth/protocols/eth,rpc,minerandinternal/cli/serverpass.Executed tests
Beyond CI's standard gates:
go build ./...,go vet ./...,gofmt -l,go mod tidy— clean apart fromthe two pre-existing
//nolintcopylocks.make lint(golangci-lint v2.11.4, the same version CI runs) — 0 issues.tests/borintegration suite — 620.9 s, exit 0. Held the batch-22 commituntil this landed.
TestReinforceMultiClientPreCompilesTest,TestV2ForkParity).go testgreen oncore(172.9 s),eth(47.5 s),core/state,core/vm/{program,runtime},core/rawdb,core/rawdb/eradb,core/types,core/types/bal,core/history,triedb,triedb/pathdb,trie,trie/bintrie,trie/trienode, alleth/tracers/...,cmd/utils,log,tests.tip rather than assumed, because these batches touch both packages:
cmd/evm'st8n golden drift and
core/vm'sTestInterruptDuringExecution/TestAbortDuringJumpfail identically before the merge.constant-normalised body diff.
New coverage:
TestStateDBCopyBinaryTrie(ports #34758's UBT copy test via Bor'striedb.VerkleDefaults, guarding the adoptedmustCopyTriebintrie case).Rollout notes
Verkle/UBT and the binary trie all remain dormant, so #34691's
StateGas,#34688's burn logs and #34714's prune points are inert on Bor's networks. The
EIP-7610 rework is a no-op for Bor's chain IDs, argued above.
docs/upstream-merges/v1.17.4/fork-register.md; deferrals and their wiringrequirements in
needs-wiring.md.Stacked PR — do not squash
This is part of a stack. Merge order matters and squash-merging any PR in it
breaks every PR above it, because squashing rewrites commits into new SHAs and
the PRs above would then re-show all of this PR's changes and conflict against
their base. Team standard for upstream syncs is a merge commit, never squash —
preserving upstream's per-commit history and authorship is the whole point.
Ready for review. The earlier note deferring reviews until every milestone
landed no longer applies — the stack is now reviewed and merged one milestone at
a time. #2340 and #2341 have merged; this PR now targets the base directly.