Skip to content

all: sync with go-ethereum v1.17.2 (upstream merge 4/6) - #2328

Merged
pratikspatil024 merged 91 commits into
upstream-merge-v1.17.4from
ppatil-upstream-v1.17.2
Sep 18, 2026
Merged

pratikspatil024 merged 91 commits into
upstream-merge-v1.17.4from
ppatil-upstream-v1.17.2

Conversation

@pratikspatil024

@pratikspatil024 pratikspatil024 commented Jul 27, 2026

Copy link
Copy Markdown
Member

Important

Reviewer guide — stacked PR 4 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 into develop once, 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#2341#2342#2343#2345#2346#2354. Start at #2308 / #2319 — every PR above inherits them, so reviewing top-down means re-reviewing.

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), and codecov/project (repo-wide coverage threshold; per-PR patch coverage is green). Kurtosis e2e occasionally flakes (~1-in-5, devtools-owned) and is re-run by hand. Full per-batch conflict-resolution reasoning is in docs/upstream-merges/.


Merge commit only — do NOT squash. Squashing this PR rewrites its commits and breaks every PR stacked above it. This is milestone 4 of a 6-PR stack.

Summary

Fourth milestone of the Bor ← go-ethereum sync to v1.17.4: takes upstream from v1.17.1 → v1.17.2 (77 first-parent commits, 4 batches of ~20). Stacked on #2325 (v1.17.1) — base is ppatil-upstream-v1.17.1, so this PR's diff is exactly this milestone.

Upstream release notes: https://github.com/ethereum/go-ethereum/releases/tag/v1.17.2

The headline is EIP-7708 (ETH transfers as logs), the first Amsterdam EIP whose content had to be reshaped rather than copied — Bor's transfer, selfdestruct and parallel-state paths all diverge from upstream's. Like every other upstream fork/EIP in this sync it is merged wired but dormant: AmsterdamBlock is nil on every shipped preset, so no behavior changes on mainnet or Amoy.

Upstream range 16783c167..be4dc0c4b (77 first-parent commits)
Batches 4 (plan rows 16–19), one merge commit each + one chores commit
Diff 154 files, +3217 / −858
Fork/EIP surfaces 5, all dormant — EIP-7778, EIP-8024 update, Amsterdam jump-table dispatch, EIP-7954, EIP-7708
Consensus behavior change on mainnet/Amoy none

Commits

Batch Boundary Commit Theme
1/4 00540f946 09c784851 EIP-7778 block gas accounting, miner prefetcher, Amsterdam jump table
2/4 77e7e5ad1 0a83ed542 codedb refactor, EIP-7954 max contract size, trienode history
3/4 e23b0cbc2 1abb57b8f stateless codedb fix, call-variant gas rework, bintrie parallel hash
4/4 be4dc0c4b 682b4c380 EIP-7708, simulateV1/getProof limits, v1.17.2 release
chores 2bc495ff9 ledger, fork-register, needs-wiring, plan, milestone triage

Reviewing this PR

docs/upstream-merges/v1.17.4/ledger.md is the review map — every non-trivial resolution is recorded there with its rationale. The sections added by this PR are the four ## v1.17.2 batch N/4 blocks, the milestone triage table, and the full-gate results. fork-register.md carries one row per fork surface; needs-wiring.md carries everything deliberately deferred.

EIP-7708 — the three adaptations worth reviewer attention

  1. Log ordering across Bor's two transfer paths. Upstream appends the log right after the balance change in Transfer. Bor has two transfer functions and an early-return V2 BlockSTM fast path whose 0x1010 LogTransfer is generated later, at settlement. The emission was factored into emitEthTransferLog and called at the same point relative to the balance change on all three paths (serial, V2 fast path, EthereumTransfer). Placing it after AddTransferLog on the serial path — the natural reading of the diff — would order the pair one way under V1 and the other under V2, i.e. a receipt-root divergence the day Amsterdam is enabled.

  2. Selfdestruct without #32919. Upstream's burn/transfer branch reads StateDB.IsNewContract, which arrives with the selfdestruct rework Bor declined. Rather than drop the branch, the signal is taken from SelfDestruct6780's existing second return value (wasNewContract), which Bor's opcode handler was discarding. Verified across all four cases. Dropping it would not have been covered by the adopted EmitLogsForBurnAccounts safety net — Bor zeroes the balance inside SelfDestruct6780, so the tx-boundary sweep skips the account and the burn log would vanish silently.

  3. ParallelStateDB.EmitLogsForBurnAccounts. New vm.StateDB method; implemented against the parallel executor's destructed map, address-sorted to match the serial executor's ordering.

Enable-time consequence to note now: once Amsterdam activates, a plain value transfer on Bor emits both the EIP-7708 system log and Bor's existing 0x1010 LogTransfer. Bloom/receipt-size change, not a correctness problem — but a product decision that should be taken deliberately, not discovered at activation. Recorded in fork-register.md.

Executed tests

Full per-milestone gate at 682b4c380:

  • go build ./... clean; go vet ./... clean bar the two pre-existing //nolint copylocks.
  • make lint (golangci-lint v2.11.4, repo config): 0 issues.
  • gofmt -l clean; go mod tidy no-op.
  • go test ./...: 148 packages pass. 4 fail, all pre-existing with no new test names — cmd/geth + cmd/devp2p/internal/ethtest (VEBLOP/non-Bor-genesis nil-deref), cmd/evm (t8n golden drift), core/vm (TestAbortDuringJump interrupt-timing flake). The latter two were re-baselined on a detached worktree at 1abb57b8f and fail identically there.
  • make test-integration: tests/bor ok, 628 s, 77.6% coverage. (Caveat recorded in the ledger: the ./tests consensus-fixture suite is a no-op in this repo — tests/testdata is absent and isn't a submodule, so those cases skip rather than run. Pre-existing.)
  • govulncheck: unchanged — the same 3 called vulns as before the milestone (x/text 0.37→0.39 available, x/crypto no fix, crypto/tls fixed in Go 1.26.5). Existing team follow-ups; no new entries from this milestone's dependency bumps.
  • Kurtosis devnet (small preset on an image built from this tip): 8/8 checks pass — ~1 s block production with validator/RPC in lockstep, 45–100 txs/block, 29 StateSynced logs, span 3 active, checkpoint 6 submitted, zero errors in either client.

EIP-7708 dormancy, proven on a live chain

The unit test proves the emission works with the gate forced on. The devnet proves it stays off. Over 50 blocks at 45–100 txs/block:

Log source Count
0xfffffffffffffffffffffffffffffffffffffffe (EIP-7708 SystemAddress) 0
0x0000000000000000000000000000000000001010 (Bor LogTransfer) 2598

The 2598 is what makes the 0 meaningful: thousands of value transfers ran through core.Transfer and none emitted a system log. A leaked gate, or a misplaced emission on any of the three transfer paths, would show a non-zero count.

Milestone triage — one item needs a team decision

Beyond conflicts, all 77 upstream PRs were triaged for Bor wiring (a PR can merge perfectly clean and still leave Bor un-wired). Result: 1 needs wiring, 5 consensus-relevant (all dormant, in the register), 7 operator-visible but no wiring, 12 deferred, 52 inert.

The one: upstream's default cache bump 1024 → 4096 MB (#33836, #33975) merged clean but has no effect on bor server. internal/cli/server/config.go carries its own Cache: 1024 with a 50/15/25/10 split whose calcPerc overwrites all four ethconfig fields — and that split against 1024 MB reproduces geth's old defaults exactly (512/154/256/102), which is evidently how it was tuned. So cmd/geth and tests get upstream's new values while production Bor stays 4× below them.

Parity is a one-line change (Cache: 4096), deliberately not taken here — it quadruples the default per-node memory footprint, which is a PoS/devops call rather than a merge decision. pos-ops pins cache per host in each BP's bor/config.toml, so deployed BPs are unaffected either way; this only moves the default for operators who don't set it. Filed as a row in needs-wiring.md.

Deferred this milestone

Six whole-feature declines, each with rationale and a re-adoption path in needs-wiring.md: #33931 (ExecuteConfig), #33816 (codedb/cachingDB), #33773 (miner OTel ctx-threading), #33648 (call-variant gas rework), #34036 (history-pruning policy), #33894 (history-import batching). Plus dependent declines that re-apply automatically when their parent lands: #34011, #34062, #34094, #33950, #33955, #33150.

⚠️ Accumulation worth flagging: core/vm/{gas_table,operations_acl}.go now carries four deferred upstream changes (#33281, #33637, #33450, #33648) plus blocked #32919, and batch 19 added a fifth entanglement — the EIP-7708 selfdestruct adaptation reads SelfDestruct6780's return value because #32919 is declined, so adopting #32919 later means revisiting that code rather than replacing it. Milestones 5 and 6 bring the gas-vector rework and gas budget into the same files. Worth a team discussion before v1.17.3.

Rollout notes

  • Not consensus-affecting on mainnet or Amoy. Every fork/EIP in this milestone is gated on IsAmsterdam, which is nil on every shipped preset. No fork block, params.Rules field, forkid input, chain preset or genesis file changed.
  • No coordinated upgrade required; backwards-compatible.
  • Operator-visible RPC changes inherited from upstream: hard caps on eth_getProof keys and eth_simulateV1 blocks/calls, a new MaxUsedGas field in the eth_simulateV1 response, eth_getLogs now erroring on an inverted block range instead of returning empty, and eth_createAccessList returning [] rather than null for empty StorageKeys.

🤖 Generated with Claude Code

fjl and others added 30 commits March 3, 2026 13:49
ethereum/go-ethereum#33916 + cmd/keeper go mod
tidy

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
In `buildPayload()`, the background goroutine uses a `select` to wait on
the recommit timer, the stop channel, and the end timer. When both
`timer.C` and `payload.stop` are ready simultaneously, Go's `select`
picks a case non-deterministically. This means the loop can enter the
`timer.C` case and perform an unnecessary `generateWork` call even after
the payload has been resolved.

Add a non-blocking check of `payload.stop` at the top of the `timer.C`
case to exit immediately when the payload has already been delivered.
Return the Amsterdam instruction set from `LookupInstructionSet` when
`IsAmsterdam` is true, so Amsterdam rules no longer fall through to the
Osaka jump table.

---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
For bal-devnet-3 we need to update the EIP-8024 implementation to the
latest spec changes: ethereum/EIPs#11306

> Note: I deleted tests not specified in the EIP bc maintaining them
through EIP changes is too error prone.
Pebble maintains a batch pool to recycle the batch object. Unfortunately
batch object must be
explicitly returned via `batch.Close` function. This PR extends the
batch interface by adding
the close function and also invoke batch.Close in some critical code
paths.

Memory allocation must be measured before merging this change. What's
more, it's an open
question that whether we should apply batch.Close as much as possible in
every invocation.
Mainnet was already overriding --cache to 4096. This PR just makes this
the default.
…#33927)

The BatchSpanProcessor queue size was incorrectly set to
DefaultMaxExportBatchSize (512) instead of DefaultMaxQueueSize (2048).

I noticed the issue on bloatnet when analyzing the block building
traces. During a particular run, the miner was including 1000
transactions in a single block. When telemetry is enabled, the miner
creates a span for each transaction added to the block. With the queue
capped at 512, spans were silently dropped when production outpaced the
span export, resulting in incomplete traces with orphaned spans. While
this doesn't eliminate the possibility of drops under extreme
load, using the correct default restores the 4x buffer between queue
capacity and export batch size that the SDK was designed around.
Fixes a regression in #33593 where a block gas limit > gasCap resulted
in more execution than the gas cap.
Eth currently has a flaky test, related to the tx fetcher.

The issue seems to happen when Unsubscribe is called while sub is nil.
It seems that chain.Stop() may be invoked before the loop starts in some
tests, but the exact cause is still under investigation through repeated
runs. I think this change will at least prevent the error.
The computation of `MAIN_STORAGE_OFFSET` was incorrect, causing the last
byte of the stem to be dropped. This means that there would be a
collision in the hash computation (at the preimage level, not a hash
collision of course) if two keys were only differing at byte 31.
…le tree (#33961)

This is an optimization that existed for verkle and the MPT, but that
got dropped during the rebase.

Mark the nodes that were modified as needing recomputation, and skip the
hash computation if this is not needed. Otherwise, the whole tree is
hashed, which kills performance.
`GenerateChain` commits trie nodes asynchronously, and it can happen
that some nodes aren't making it to the db in time for `GenerateChain`
to open it and find the data it is looking for.
Add nil checks to prevent potential panics when keystore backend is
unavailable in the Clef signer API.
Reduce allocations in calculation of tx cost.

---------

Co-authored-by: weixie.cui <weixie.cui@okg.com>
Co-authored-by: Sina M <1591639+s1na@users.noreply.github.com>
Updates go-eth-kzg to
https://github.com/crate-crypto/go-eth-kzg/releases/tag/v1.5.0
Significantly reduces the allocations in VerifyCellProofBatch which is
around ~5% of all allocations on my node

---------

Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
I observed failing tests in Hive `engine-withdrawals`:

-
https://hive.ethpandaops.io/#/test/generic/1772351960-ad3e3e460605c670efe1b4f4178eb422?testnumber=146
-
https://hive.ethpandaops.io/#/test/generic/1772351960-ad3e3e460605c670efe1b4f4178eb422?testnumber=147

```shell
  DEBUG (Withdrawals Fork on Block 2): NextPayloadID before getPayloadV2:
  id=0x01487547e54e8abe version=1
  >> engine_getPayloadV2("0x01487547e54e8abe")
  << error: {"code":-38005,"message":"Unsupported fork"}
  FAIL: Expected no error on EngineGetPayloadV2: error=Unsupported fork
```
 
The same failure pattern occurred for Block 3.

Per Shanghai engine_getPayloadV2 spec, pre-Shanghai payloads should be
accepted via V2 and returned as ExecutionPayloadV1:
- executionPayload: ExecutionPayloadV1 | ExecutionPayloadV2
- ExecutionPayloadV1 MUST be returned if payload timestamp < Shanghai
timestamp
- ExecutionPayloadV2 MUST be returned if payload timestamp >= Shanghai
timestamp

Reference:
-
https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#engine_getpayloadv2

Current implementation only allows GetPayloadV2 on the Shanghai fork
window (`[]forks.Fork{forks.Shanghai}`), so pre-Shanghai payloads are
rejected with Unsupported fork.

If my interpretation of the spec is incorrect, please let me know and I
can adjust accordingly.

---------

Co-authored-by: muzry.li <muzry.li1@ambergroup.io>
This PR fixes a regression introduced in https://github.com/ethereum/go-ethereum/pull/33836/changes

Before PR 33836, running mainnet would automatically bump the cache size
to 4GB and trigger a cache re-calculation, specifically setting the key-value 
database cache to 2GB.
 
After PR 33836, this logic was removed, and the cache value is no longer
recomputed if no command line flags are specified. The default key-value 
database cache is 512MB.

This PR bumps the default key-value database cache size alongside the
default cache size for other components (such as snapshot) accordingly.
We got a report for a bug in the tracing journal which has the
responsibility to emit events for all state that must be reverted.

The edge case is as follows: on CREATE operations the nonce is
incremented. When a create frame reverts, the nonce increment associated
with it does **not** revert. This works fine on master. Now one step
further: if the parent frame reverts tho, the nonce **should** revert
and there is the bug.
This PR contains two changes:

Firstly, the finalized header will be resolved from local chain if it's
not recently announced via the `engine_newPayload`. 

What's more importantly is, in the downloader, originally there are two
code paths to push forward the pivot point block, one in the beacon 
header fetcher (`fetchHeaders`), and another one is in the snap content 
processer (`processSnapSyncContent`).

Usually if there are new blocks and local pivot block becomes stale, it
will firstly be detected by the `fetchHeaders`. `processSnapSyncContent` 
is fully driven by the beacon headers and will only detect the stale pivot 
block after synchronizing the corresponding chain segment. I think the 
detection here is redundant and useless.
…3984)

The `--remove.chain` flag incorrectly described itself as selecting
"state data" for removal, which could mislead operators into removing
the wrong data category. This corrects the description to accurately
reflect that the flag targets chain data (block bodies and receipts).
This PR allows users to prune their nodes up to the Prague fork. It
indirectly depends on #32157 and can't really be merged before eraE
files are widely available for download.

The `--history.chain` flag becomes mandatory for `prune-history`
command. Here I've listed all the edge cases that can happen and how we
behave:

## prune-history Behavior

| From        | To           | Result                   |
|-------------|--------------|--------------------------|
| full        | postmerge    | ✅ prunes                |
| full        | postprague   | ✅ prunes                |
| postmerge   | postprague   | ✅ prunes further        |
| postprague  | postmerge    | ❌ can't unprune         |
| any         | all          | ❌ use import-history    |


## Node Startup Behavior

| DB State | Flag | Result |

|-------------|--------------|----------------------------------------------------------------|
| fresh | postprague | ✅ syncs from Prague |
| full | postprague | ❌ "run prune-history first" |
| postmerge | postprague | ❌ "run prune-history first" |
| postprague | postmerge | ❌ "can't unprune, use import-history or fix
flag" |
| pruned | all | ✅ accepts known prune points |
This PR adds a cmd tool fetchpayload which connects to a
node and gets all the information in order to create a serialized
payload that can then be passed to the zkvm.
@pratikspatil024
pratikspatil024 marked this pull request as ready for review August 13, 2026 06:56

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@pratikspatil024

Copy link
Copy Markdown
Member Author

@claude review

@pratikspatil024
pratikspatil024 requested a lite review from Copilot August 13, 2026 06:58
@pratikspatil024

Copy link
Copy Markdown
Member Author

codegenie review

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

🧞 Codegenie Review

Warning

Review incomplete. Some review or verification work did not complete. Planning also fell back to deterministic default coverage. Treat the results below as partial and consider rerunning.

Sorry, this review is incomplete. The allotted max token limit of 8000000 (config review.maxBudgetTokens) was reached and the review has been degraded. Raise the limit for a complete review.

⚠️ Found 3 verified issues.

Coverage

Partial review: 189 hunks were not reviewed because budget was exhausted before dispatch.
Reviewed 195/386 hunks before stopping.
Incomplete work: skipped 2, failed 189, verification incomplete 13.
Coverage levels: deep 0, normal 384, light 0, skip 2.
Planning was degraded and deterministic fallbacks were used.
Unreviewed hunks by file:

  • accounts/abi/bind/backends/simulated.go: 1 hunk (budget stopped before dispatch)
  • build/ci.go: 2 hunks (budget stopped before dispatch)
  • cmd/devp2p/internal/v5test/framework.go: 1 hunk (budget stopped before dispatch)
  • cmd/evm/internal/t8ntool/transaction.go: 2 hunks (budget stopped before dispatch)
  • cmd/geth/dbcmd.go: 1 hunk (budget stopped before dispatch)
  • cmd/geth/main.go: 1 hunk (budget stopped before dispatch)
  • cmd/geth/snapshot.go: 5 hunks (budget stopped before dispatch)
  • cmd/keeper/getpayload_example.go: 1 hunk (budget stopped before dispatch)
  • cmd/keeper/getpayload_wasm.go: 1 hunk (budget stopped before dispatch)
  • cmd/keeper/stubs.go: 1 hunk (budget stopped before dispatch)
  • cmd/utils/flags.go: 2 hunks (budget stopped before dispatch)
  • console/console.go: 1 hunk (budget stopped before dispatch)
  • 91 additional files omitted.
  • Budget stopped review work (token limit reached).
  • Verification incomplete for 13 candidates.
  • planner degraded; deterministic default plan used
  • go.sum: lockfile
  • semantic composition skipped; deterministic fallback used

⚠️ Findings

🔵 Medium: fetchpayload rlp/hex output drops witness Codes; json output keeps them

File: cmd/fetchpayload/main.go:106
Confidence: medium

Impact: The tool advertises writing a payload "in the format consumed by cmd/keeper", but rlp.EncodeToBytes(payload) dispatches to Witness.EncodeRLP, which emits the 3-field BorWitness form (context, headers, state) and never writes w.Codes. cmd/keeper decodes that same Payload with rlp.DecodeBytes; DecodeRLP's BorWitness branch sets w.Codes to an empty map, then hands the witness to core.ExecuteStateless. If stateless execution needs contract bytecode from Codes, keeper fails (exit 10) or produces a wrong root; the failure appears at consumption time, far from this tool. The json output is unaffected because it serializes ExtWitness with Codes populated, so the three formats produced by the same invocation carry different data.
A debugging/fixture tool that silently produces content-incomplete payload files wastes triage time: the rlp and hex artifacts differ from the json artifact for the same block, and the loss is only observable when keeper executes them. Either the tool should serialize an encoding that preserves codes, or the omission should be documented so users know rlp/hex payloads are not self-contained.

Evidence:

Changed code:

payload := Payload{
	ChainID: chainID.Uint64(),
	Block: block,
	Witness: witness,
}
// Encode payload as RLP (shared by "rlp" and "hex" formats).
rlpBytes, err := rlp.EncodeToBytes(payload)

core/stateless/encoding.go (Payload embeds *stateless.Witness, so rlp.EncodeToBytes dispatches to this custom encoder, which serializes only w.State and never w.Codes.):

// EncodeRLP serializes a witness as RLP using the canonical BorWitness 3-field
// format. Only state trie nodes are encoded; contract bytecodes are not
// included in the wire format.
func (w *Witness) EncodeRLP(wr io.Writer) error {
	w.lock.RLock()
	defer w.lock.RUnlock()
	bw := &BorWitness{
 Context: w.context,
 Headers: w.Headers,
 State: make([][]byte, 0, len(w.State)),
	}
	for node := range w.State {
...

core/stateless/encoding.go (Confirms the round trip is lossy: a consumer re-decoding the .rlp/.hex file gets Codes == empty map, not the codes returned by debug_executionWitness.):

// When decoding BorWitness, State items are placed into w.State and w.Codes
// is left empty, since codes are not part of the BorWitness wire format.
func (w *Witness) DecodeRLP(s *rlp.Stream) error {
	...
	var bw BorWitness
	if err := rlp.DecodeBytes(raw, &bw); err == nil {
 w.context = bw.Context
 w.Headers = bw.Headers
 w.Codes = make(map[string]struct{})
 ...

cmd/keeper/main.go (The named consumer decodes this exact RLP Payload and feeds the (Codes-empty) witness straight into ExecuteStateless.):

var payload Payload
rlp.DecodeBytes(input, &payload)
...
crossStateRoot, crossReceiptRoot, _, _, err := core.ExecuteStateless(chainConfig, vmConfig, payload.Block, payload.Witness, nil, nil, nil)

cmd/fetchpayload/main.go (The json format serializes ExtWitness (which has a Codes field populated from the RPC response), so the three advertised formats are not equivalent in content.):

case "json":
	data, err = marshalJSONPayload(chainID, block, &extWitness)

Suggested fix: Confirm whether core.ExecuteStateless requires Witness.Codes for this Bor witness format. If it does, serialize a codes-preserving encoding for the rlp/hex outputs (e.g. encode the ExtWitness form, which DecodeRLP already accepts via its 5-field fallback) so the file round-trips. If codes are genuinely redundant because State already contains them, reconcile the contradictory BorWitness/EncodeRLP doc comments and note in the fetchpayload package doc that rlp/hex payloads omit the separate Codes list.

Suggested test: Round-trip test in cmd/fetchpayload: build a Payload whose Witness has a non-empty Codes set, run rlp.EncodeToBytes then rlp.DecodeBytes into a fresh Payload, and assert on Codes — either that it survives (after the fix) or, if the loss is intentional, assert it is empty and document the invariant so the asymmetry with the json output is pinned by a test.

⚪ Low: traverseState now always reports slots=0 after extracting traverseStorage

File: cmd/geth/snapshot.go:485
Confidence: high

Impact: Running geth snapshot traverse-state (no --account) still prints the "Traversing state"/"State is complete" summary lines, but slots is now permanently 0 because the extracted traverseStorage keeps its slot count local and returns only an error. Operators using the command to verify state completeness lose the storage-slot count and may read slots=0 as an empty/broken state.
The command's caller-visible output silently degrades: a previously meaningful diagnostic counter is now a constant zero, which can mislead pruning/state verification workflows. It is purely diagnostic (no state correctness impact), hence low severity, but it is an unintended regression of the refactor.

Evidence:

Changed code:

		if acc.Root != types.EmptyRootHash {
			err := traverseStorage(trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root), triedb, false, false)
			if err != nil {
				return err
			}
		}

cmd/geth/snapshot.go (Head-side read of traverseState (lines ~464-506) confirms slots is declared and printed in both progress and completion logs but is no longer incremented anywhere after the inlined storage loop was replaced by traverseStorage.):

var (
	accounts   int
	slots      int
	codes      int
	...
)
...
log.Info("Traversing state", "accounts", accounts, "slots", slots, "codes", codes, ...)
...
log.Info("State is complete", "accounts", accounts, "slots", slots, "codes", codes, ...)

cmd/geth/snapshot.go (traverseStorage counts slots in a function-local variable and returns only error, so the per-account slot count is not propagated back to traverseState.):

func traverseStorage(id *trie.ID, db *triedb.Database, report bool, detail bool) error {
	...
	slots += 1
	...
	return nil
}

cmd/geth/snapshot.go (Base-side read shows the removed loop was the only place the outer slots counter was incremented.):

storageIter := trie.NewIterator(storageIt)
for storageIter.Next() {
	slots += 1
	...
}

Suggested fix: Have traverseStorage return the slot (and optionally node) count, e.g. func traverseStorage(...) (int, error), and accumulate it in traverseState: n, err := traverseStorage(...); slots += n. Alternatively drop slots from traverseState's log lines so the output does not advertise a stale zero.

Suggested test: Add a cmd/geth test (or manual run) over a small state with at least one contract account holding storage, asserting the "State is complete" log line reports a non-zero slots value.

⚪ Low: Verkle fast path drops updateTrie()'s pending-area diagnostic and StorageUpdated/StorageDeleted metrics

File: core/state/statedb.go:1611
Confidence: high

Impact: In verkle/binary-trie mode, IntermediateRoot now applies storage diffs inline instead of via (*stateObject).updateTrie. A key present in uncommittedStorage but absent from pendingStorage is silently skipped: the !exist case is folded into the same continue as the noop case, so the upstream log.Error("Storage slot is not found in pending area", ...) internal-consistency diagnostic never fires. The same loop also never increments s.StorageUpdated / s.StorageDeleted, so storageUpdatedMeter and storageDeletedMeter report zero storage activity for all verkle-mode blocks.
Control flow for the !exist case is identical (both implementations continue), so no root or storage value changes; the concrete impact is bounded to observability. Still, if a state-diff bug ever leaves a slot out of the pending area, verkle mode loses the only signal that would attribute the resulting root mismatch, and storage update/delete meters silently read zero for verkle nodes, which can mislead capacity and regression analysis.

Evidence:

Changed code:

for key, origin := range obj.uncommittedStorage {
	value, exist := obj.pendingStorage[key]
	if value == origin || !exist {
 continue
	}
	if (value != common.Hash{}) {
 if err := s.trie.UpdateStorage(addr, key[:], common.TrimLeftZeroes(value[:])); err != nil {
 s.setError(err)
 }
	} else {
 if err := s.trie.DeleteStorage(addr, key[:]); err != nil {
 s.setError(err)
...

core/state/state_object.go (Decisive callee branch (read in full, lines 344-390 of head): the bypassed implementation logs the missing-pending-slot invariant violation and increments StorageUpdated/StorageDeleted. The inlined verkle loop does neither.):

for key, origin := range s.uncommittedStorage {
	value, exist := s.pendingStorage[key]
	if value == origin {
 continue
	}
	if !exist {
 log.Error("Storage slot is not found in pending area", "address", s.address, "slot", key)
 continue
	}
	if (value != common.Hash{}) {
 if err := tr.UpdateStorage(s.address, key[:], common.TrimLeftZeroes(value[:])); err != nil { ... }
 s.db.StorageUpdated.Add(1)
...

core/state/statedb.go (Shows the dropped counters are reported to metrics meters (statedb.go:2085-2087), so the omission is an observability regression in verkle/binary-trie mode rather than dead state.):

storageUpdatedMeter.Mark(s.StorageUpdated.Load())
accountDeletedMeter.Mark(int64(s.AccountDeleted))
storageDeletedMeter.Mark(s.StorageDeleted.Load())

Suggested fix: Restore parity with updateTrie() on the inlined path: split the !exist case back out with its log.Error("Storage slot is not found in pending area", "address", addr, "slot", key), and call s.StorageUpdated.Add(1) / s.StorageDeleted.Add(1) alongside the corresponding UpdateStorage/DeleteStorage calls.

Suggested test: Add a verkle-mode StateDB test that sets and clears storage slots on an account, runs IntermediateRoot, and asserts s.StorageUpdated and s.StorageDeleted match the number of non-zero writes and deletions (matching the counts the non-verkle updateTrie path produces for the same mutations).

🙋 Needs Human Attention

  • Does every path that calls dialsched.inboundPending(id) in p2p/server.go guarantee a matching inboundCompleted(id) call (including error/early-return and panic paths), so pendingInbound entries cannot leak and permanently block dials to that node via checkDial's errPendingInbound?

    • Files: p2p/dial.go, p2p/dial_test.go, p2p/server.go
    • Symbols: SetupConn, addPendingCh, checkDial, checkInboundConn, errPendingInbound, inboundCompleted
    • Reason: loop now stores IDs in d.pendingInbound on addPendingCh and only removes them on remPendingCh; checkDial rejects nodes present in pendingInbound. If a server-side inbound setup path returns without calling inboundCompleted, the ID stays in the map for the scheduler's lifetime and dials (including static dials) to that node are blocked indefinitely. server.go:854 shows inboundPending is called after postHandshakeChecks; the paired cleanup path was not inspected before budget exhaustion. Related reasons: Packet reviewer could not resolve this question from the reviewed context. inboundPending inserts an entry into dialScheduler.pendingInbound which checkDial uses to suppress dials; only inboundCompleted removes it. If any inbound failure path in server.go skips inboundCompleted (e.g. early return before defer registration), the node ID is excluded from dialing for the process lifetime and the map grows unbounded. Caller sites could not be inspected before tool budget exhaustion. Grouped from 8 related hints across 4 packets.
  • Does EIP-8024's EXCHANGE immediate encoding really permit imm bytes 0x50 and 0x51 (which decodePair maps to pairs (14,16) and (14,15)), and is the missing pair (15,16) (would require imm 0x60, still rejected) intentional?

    • Files: core/vm/instructions.go, core/vm/instructions_test.go
    • Symbols: TestEIP8024_Execution, decodePair, decodeSingle, opDupN, opExchange, opSwapN
    • Reason: The changed guard widens the accepted immediate set from 208 to 210 values, making imm 0x50/0x51 consensus-valid instead of ErrInvalidOpCode. This is a consensus-visible validity boundary; decodePair's comment ('forbidden bytes [82,127]', '210 valid pairs') matches the new bound, but the exact spec-permitted set was not verified against EIP-8024. Related reasons: Both old and new formulas are bijections onto the same output sets, so the remap is silent; only upstream/EIP reference vectors can decide whether the new mapping is the fix or a regression. If the removal mirrors upstream verbatim, severity is lower; if this fork dropped cases while keeping the guards, the coverage gap on opDupN's x > 90 && x < 128 guard and SWAPN/EXCHANGE underflow checks is a real regression. Grouped from 6 related hints across 3 packets.
  • Does pruneHistoryCommand (cmd/geth/chaincmd.go:206) register utils.ChainHistoryFlag in its Flags list, and does utils.ChainHistoryFlag exist with name "history.chain"?

    • Files: cmd/geth/chaincmd.go, cmd/utils/flags.go, docs/upstream-merges/v1.17.4/needs-wiring.md
    • Symbols: ChainHistoryFlag, GetPrunePoint, MakeChain, makeConfigNode, pruneHistory, pruneHistoryCommand
    • Reason: The new mandatory flag check makes the subcommand unusable if the flag is not registered on the command; this is the single unresolved predicate for the reported finding. Related reasons: Packet reviewer could not resolve this question from the reviewed context. Grouped from 3 related hints across 2 packets.
  • In this fork, is f.tail stored as an absolute (offset-inclusive) item number by repair()/validate() at open time, the same way f.head is (freezer.head.Add(offset) in NewFreezer)? If repair sets tail relative while TruncateTail stores an absolute tail, the new 'if f.head.Load() < tail { f.head.Store(tail) }' guard compares/stores mixed-basis values and could push head forward by up to offset items.

    • Files: core/rawdb/freezer.go, triedb/pathdb/history.go
    • Symbols: (*Freezer).MigrateTable, (*Freezer).TruncateTail, (*Freezer).repair, (*Freezer).validate, Freezer.Ancients, Freezer.Tail
    • Reason: Upstream's TruncateTail has no offset concept; this fork subtracts f.offset when calling table.truncateTail but compares the un-adjusted tail against f.head. Correctness of the new head bump depends on f.tail/tail being absolute like f.head, which I could not confirm because repair()/validate() could not be read before budget exhaustion. Related reasons: Packet reviewer could not resolve this question from the reviewed context. truncate() escalates any truncateFromHead error to log.Crit, so a guard failure here aborts startup instead of initializing trienode history. Grouped from 3 related hints across 2 packets.
  • Once initerState reaches stateStalled, update() never re-evaluates progress (the ticker branch continues on stateStalled), so canExit() in indexIniter.run stays permanently true even if sync later resumes. Is that the intended terminal state in upstream v1.17.x?

    • Files: triedb/pathdb/history_indexer.go, triedb/pathdb/history_indexer_state.go
    • Symbols: canExit, indexIniter.index, indexIniter.recover, indexIniter.remain, indexIniter.run, initerState.is
    • Reason: stateStalled is terminal: the ticker branch skips all further checks for stateSynced/stateStalled, so a node that resumes syncing is still reported non-syncing to the index initializer, which may let initial indexing exit early. Needs confirmation against upstream behavior before treating as a defect. Related reasons: Packet reviewer could not resolve this question from the reviewed context. The new batching gate performs unsigned subtraction without the last<indexed guard that remain() uses; confirming reachability decides whether the sync-phase batching guard is defeated. Grouped from 3 related hints across 2 packets.

Additional unresolved notes suppressed: 35.

Stats

  • 🤖 Model: anthropic claude-opus-5 high
  • 🧞 Codegenie: v0.5.5 (58f82a9b2c)
  • Elapsed time: 15m 42s
  • Git: 0xPolygon/bor from ppatil-upstream-v1.17.1 to ppatil-upstream-v1.17.2 (184ef4347a)
  • Posting: 3 inline
  • Review completeness: partial.
  • Usage: model calls 377, tokens 8105646, cost $37.1021.
  • Effective caps: tokens 8000000.
  • Budget overruns: stage 9 tokens 8004839/8000000.
  • Budget dispatch blocks: stage 7 tokens 6812912/8000000; stage 7 tokens 6809525/8000000; stage 7 tokens 6809301/8000000; stage 7 tokens 6808813/8000000; stage 7 tokens 6808802/8000000; stage 7 tokens 6809778/8000000; stage 7 tokens 6810237/8000000; stage 7 tokens 6810273/8000000; stage 7 tokens 6811225/8000000; stage 7 tokens 6810612/8000000; stage 7 tokens 6810944/8000000; stage 7 tokens 6808763/8000000; stage 7 tokens 6810429/8000000; stage 7 tokens 6809730/8000000; stage 7 tokens 6809108/8000000; stage 7 tokens 6810248/8000000; stage 7 tokens 6808700/8000000; stage 7 tokens 6810180/8000000; stage 7 tokens 6809022/8000000; stage 7 tokens 6809259/8000000; stage 7 tokens 6808973/8000000; stage 7 tokens 6806976/8000000; stage 7 tokens 6808371/8000000; stage 7 tokens 6808395/8000000; stage 7 tokens 6809144/8000000; stage 7 tokens 6810200/8000000; stage 7 tokens 6810359/8000000; stage 7 tokens 6809351/8000000; stage 7 tokens 6809367/8000000; stage 7 tokens 6809285/8000000; stage 7 tokens 6809545/8000000; stage 7 tokens 6808971/8000000; stage 7 tokens 6809555/8000000; stage 7 tokens 6810511/8000000; stage 7 tokens 6808973/8000000; stage 7 tokens 6808782/8000000; stage 7 tokens 6810139/8000000; stage 7 tokens 6808989/8000000; stage 7 tokens 6809468/8000000; stage 7 tokens 6809307/8000000; stage 7 tokens 6809207/8000000; stage 7 tokens 6808749/8000000; stage 7 tokens 6809415/8000000; stage 7 tokens 6809070/8000000; stage 7 tokens 6808693/8000000; stage 7 tokens 6808633/8000000; stage 7 tokens 6810374/8000000; stage 7 tokens 6808941/8000000; stage 7 tokens 6809708/8000000; stage 7 tokens 6809031/8000000; stage 7 tokens 6809844/8000000; stage 7 tokens 6806463/8000000; stage 7 tokens 6808562/8000000; stage 7 tokens 6809047/8000000; stage 7 tokens 6809002/8000000; stage 7 tokens 6809172/8000000; stage 7 tokens 6809325/8000000; stage 7 tokens 6808886/8000000; stage 7 tokens 6809295/8000000; stage 7 tokens 6809738/8000000; stage 7 tokens 6809675/8000000; stage 7 tokens 6808699/8000000; stage 7 tokens 6809199/8000000; stage 7 tokens 6809495/8000000; stage 7 tokens 6807151/8000000; stage 7 tokens 6808972/8000000; stage 7 tokens 6808751/8000000; stage 7 tokens 6808596/8000000; stage 7 tokens 6806386/8000000; stage 7 tokens 6809068/8000000; stage 7 tokens 6808901/8000000; stage 7 tokens 6808985/8000000; stage 7 tokens 6809045/8000000; stage 7 tokens 6809621/8000000; stage 7 tokens 6809853/8000000; stage 7 tokens 6809992/8000000; stage 7 tokens 6808358/8000000; stage 7 tokens 6808377/8000000; stage 7 tokens 6809311/8000000; stage 7 tokens 6810342/8000000; stage 7 tokens 6809826/8000000; stage 7 tokens 6809224/8000000; stage 7 tokens 6807370/8000000; stage 7 tokens 6809028/8000000; stage 7 tokens 6808847/8000000; stage 7 tokens 6809973/8000000; stage 7 tokens 6808788/8000000; stage 7 tokens 6809149/8000000; stage 7 tokens 6806344/8000000; stage 7 tokens 6808271/8000000; stage 7 tokens 6806325/8000000; stage 7 tokens 6806242/8000000; stage 7 tokens 6810360/8000000; stage 7 tokens 6806237/8000000; stage 7 tokens 6809629/8000000; stage 7 tokens 6823318/8000000; stage 7 tokens 6821964/8000000; stage 7 tokens 6814607/8000000; stage 7 tokens 6813661/8000000; stage 7 tokens 6812332/8000000; stage 7 tokens 6811928/8000000; stage 7 tokens 6812020/8000000; stage 7 tokens 6811501/8000000; stage 7 tokens 6812290/8000000; stage 7 tokens 6810834/8000000; stage 7 tokens 6811566/8000000; stage 7 tokens 6810423/8000000; stage 7 tokens 6811106/8000000; stage 7 tokens 6810895/8000000; stage 7 tokens 6811172/8000000; stage 7 tokens 6811592/8000000; stage 7 tokens 6810901/8000000; stage 7 tokens 6811311/8000000; stage 7 tokens 6811036/8000000; stage 7 tokens 6811384/8000000; stage 7 tokens 6811263/8000000; stage 7 tokens 6811031/8000000; stage 7 tokens 6811195/8000000; stage 7 tokens 6810837/8000000; stage 7 tokens 6810828/8000000; stage 7 tokens 6810492/8000000; stage 7 tokens 6810269/8000000; stage 7 tokens 6810621/8000000; stage 7 tokens 6811097/8000000; stage 7 tokens 6810062/8000000; stage 7 tokens 6810600/8000000; stage 7 tokens 6810470/8000000; stage 7 tokens 6810606/8000000; stage 7 tokens 6810483/8000000; stage 7 tokens 6810465/8000000; stage 7 tokens 6810418/8000000; stage 7 tokens 6810549/8000000; stage 7 tokens 6810375/8000000; stage 7 tokens 6810084/8000000; stage 7 tokens 6810925/8000000; stage 7 tokens 6810889/8000000; stage 7 tokens 6810671/8000000; stage 7 tokens 6811305/8000000; stage 7 tokens 6810230/8000000; stage 7 tokens 6809704/8000000; stage 7 tokens 6811075/8000000; stage 7 tokens 6810645/8000000; stage 7 tokens 6809788/8000000; stage 7 tokens 6809752/8000000; stage 7 tokens 6809811/8000000; stage 7 tokens 6810334/8000000; stage 7 tokens 6811063/8000000; stage 7 tokens 6810198/8000000; stage 7 tokens 6810146/8000000; stage 7 tokens 6810585/8000000; stage 7 tokens 6810584/8000000; stage 7 tokens 6810728/8000000; stage 7 tokens 6810204/8000000; stage 7 tokens 6810702/8000000; stage 7 tokens 6809477/8000000; stage 7 tokens 6809742/8000000; stage 7 tokens 6809625/8000000; stage 7 tokens 6810032/8000000; stage 7 tokens 6820351/8000000; stage 7 tokens 6813434/8000000; stage 7 tokens 6808690/8000000; stage 7 tokens 6811083/8000000; stage 7 tokens 6829751/8000000; stage 7 tokens 6836942/8000000; stage 9 tokens 8001469/8000000; stage 9 tokens 8007285/8000000; stage 9 tokens 8004394/8000000; stage 9 tokens 8001888/8000000; stage 9 tokens 8003470/8000000; stage 9 tokens 8009735/8000000; stage 9 tokens 8013933/8000000; stage 9 tokens 8011052/8000000; stage 9 tokens 8006834/8000000; stage 9 tokens 8004634/8000000; stage 9 tokens 8002441/8000000; stage 9 tokens 8008263/8000000; stage 9 tokens 8003928/8000000; stage 9 tokens 8002464/8000000; stage 9 tokens 8012850/8000000; stage 9 tokens 8017865/8000000; stage 9 tokens 8025979/8000000; stage 10 tokens 8105646/8000000.
  • Local context pressure: 40 tool-budget rejections, 151 degraded tool results, 65 degraded hunks, 35 unresolved notes suppressed.

View Workflow Job

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upstream-merge milestone syncing Bor’s fork with go-ethereum v1.17.2, bringing in a large set of upstream changes across trie/pathdb history handling, freezer/ancients behavior, EVM gas accounting plumbing (Amsterdam-gated), p2p dialing/discovery improvements, and related test/CLI adjustments.

Changes:

  • Introduces new/updated primitives for gas accounting (core.GasPool), receipt cumulative gas tracking, and Amsterdam-gated behaviors (incl. EIP-7708 surfaces, EIP-7954 limits).
  • Expands and hardens storage/history subsystems: pathdb history repair/indexing, freezer tail truncation behavior, batch resource closing, and verkle/bintrie hashing improvements.
  • Updates p2p and RPC/user-facing tooling: avoid outbound dials to pending inbound peers, resolve bootnode hostnames, add RPC limits and error behaviors, and extend pruning history modes.

Reviewed changes

Copilot reviewed 154 out of 155 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
triedb/pathdb/reader.go Historic reader error handling change
triedb/pathdb/history.go History repair truncation logic
triedb/pathdb/history_indexer_test.go Indexer test updated for new args
triedb/pathdb/history_indexer_state.go New sync-state tracker for indexer
triedb/pathdb/database.go Pass new index-delay config
triedb/pathdb/database_test.go Enable no-delay indexing in tests
triedb/pathdb/config.go Add NoHistoryIndexDelay config
triedb/pathdb/buffer.go Close batch after flush
trie/trie_test.go Add Close to batch test stub
trie/levelstats.go Add LevelStats deep copy
trie/bintrie/trie.go Deserialize node with provided hash
trie/bintrie/stem_node.go Cache hash + pooled sha256 usage
trie/bintrie/stem_node_test.go Ensure recompute flag in hash test
trie/bintrie/key_encoding.go Rework key derivation + overflow handling
trie/bintrie/iterator.go Handle nil resolved nodes + backtracking
trie/bintrie/internal_node.go Cached hash + parallel hashing
trie/bintrie/internal_node_test.go Recompute flag adjustments in tests
trie/bintrie/hasher.go New sha256 hasher pool
trie/bintrie/hashed_node.go Deserialize with hash parameter
trie/bintrie/empty.go Ensure new stem nodes marked dirty
trie/bintrie/binary_node.go Add DeserializeNodeWithHash API
tests/state_test_util.go Use NewGasPool in state tests
tests/bor/helper.go Adjust ApplyTransaction signature + gaspool
signer/core/uiapi.go Avoid extra allocs; keystore nil check
rlp/raw.go Add RawList.AppendList
rlp/raw_test.go Tests for RawList.AppendList
rlp/encode_test.go Add EncoderBuffer.Size test
rlp/encbuffer.go Implement EncoderBuffer.Size
params/protocol_params.go Add Amsterdam code size + system log topics
p2p/server.go Track pending inbound IDs for dialer
p2p/discover/table.go Resolve bootnode hostnames via DNS
p2p/discover/table_test.go Test DNS hostname fallback resolution
p2p/dial.go Avoid dialing nodes with pending inbound
p2p/dial_test.go Test pending-inbound dial suppression
miner/worker.go GasPool API updates; prefetcher signature updates
miner/worker_test.go Update gaspool init
miner/worker_prefetch_unit_test.go Update gaspool init
miner/payload_building.go Prefer stop signal before timer work
internal/ethapi/simulate.go Use NewGasPool + cumulative gas tracking
internal/ethapi/errors.go Map initcode error to vm package
internal/ethapi/bor_api_test.go Update witness constructor signature
internal/ethapi/api.go Add getProof key cap; gaspool nil handling; slotNumber encoding
go.sum Dependency checksum updates
go.mod Bump go-eth-kzg and karalabe/hid
ethdb/pebble/pebble.go Implement batch.Close
ethdb/memorydb/memorydb.go Implement batch.Close (noop)
ethdb/leveldb/leveldb.go Implement batch.Close (noop)
ethdb/batch.go Add Close() to Batch interface
eth/tracers/tracers_test.go ApplyMessage now accepts nil gaspool
eth/tracers/logger/access_list_tracer.go Stable/safe storageKeys marshaling
eth/tracers/internal/tracetest/prestate_test.go ApplyMessage nil gaspool update
eth/tracers/internal/tracetest/flat_calltrace_test.go ApplyMessage nil gaspool update
eth/tracers/internal/tracetest/erc7562_tracer_test.go ApplyMessage nil gaspool update
eth/tracers/internal/tracetest/calltrace_test.go ApplyMessage nil gaspool update
eth/tracers/api.go Use nil gaspool; traceTx usedGas via GasPool
eth/tracers/api_test.go ApplyMessage nil gaspool update
eth/state_accessor.go ApplyMessage nil gaspool update
eth/protocols/wit/peer_test.go Update witness constructor signature
eth/peer_test.go Update witness APIs + AddState signature
eth/handler_wit_test.go Update witness constructor signature
eth/gasestimator/gasestimator.go ApplyMessage nil gaspool update
eth/filters/filter.go Error on inverted block range
eth/filters/filter_test.go Update test expectation for range error
eth/filters/api.go Subscription setup cleanup; pruned history guard
eth/fetcher/witness_manager_test.go Update witness constructor signature
eth/fetcher/block_fetcher_test.go Update witness constructor signature
eth/fetcher/block_fetcher_race_test.go Update witness constructor signature
eth/ethconfig/config.go Update cache split defaults
eth/catalyst/simulated_beacon.go Amsterdam payload version + slot number
eth/catalyst/api.go Fetch unknown forkchoice head; finalized fallback
eth/catalyst/api_test.go Allow GetPayloadV2 pre-Shanghai
docs/upstream-merges/v1.17.4/plan.md Mark v1.17.2 batches merged
docs/upstream-merges/v1.17.4/fork-register.md Record new fork/EIP surfaces
core/vm/jump_table_export.go Add Amsterdam instruction set export
core/vm/interpreter_test.go Transfer signature includes rules
core/vm/interface.go Add EmitLogsForBurnAccounts to StateDB
core/vm/instructions.go EIP-7708 selfdestruct logs; EIP-8024 decoding changes
core/vm/instructions_test.go Update EIP-8024 execution tests
core/vm/gas_table.go Use initcode-size helper check
core/vm/gas_table_test.go Update Transfer signature; config selection
core/vm/evm.go Transfer now receives rules
core/vm/dispatch_test.go Update Transfer signature in tests
core/vm/dispatch_bench_test.go Update Transfer signature in benches
core/vm/common.go Add CheckMax(Code
core/v2_witness_regen_test.go Update witness constructor signature
core/v2_serial_parity_fuzz_test.go GasPool API updates
core/v2_selfdestruct_self_beneficiary_test.go GasPool API updates
core/v2_pre_exec_system_call_test.go GasPool API updates
core/v2_metamorphic_parity_test.go GasPool API updates
core/v2_blockstm_test.go GasPool API updates
core/v1_differential_test.go GasPool API updates
core/types/transaction.go Reduce allocations in Cost()
core/types/log.go Add EIP-7708 log constructors
core/txpool/validation.go Use vm initcode-size helper
core/txpool/legacypool/legacypool.go Simplify Get; use types.Sender helper
core/tracing/journal.go Fix nonce journaling across frame reverts
core/tracing/journal_test.go Add parent-revert nonce test
core/tracing/hooks.go Comment/name adjustments
core/stateless/witness.go Optional stats + AddState(owner)
core/stateless/stats.go Add WitnessStats copy
core/stateless/encoding.go Export FromExtWitness
core/stateless/database_test.go Update witness constructor signature
core/state/statedb_hooked.go Forward EmitLogsForBurnAccounts
core/state/state_object.go Skip redundant verkle trie commits
core/state/reader.go Hash inputs via slices; witness owner passed
core/state/parallel_statedb.go Implement EmitLogsForBurnAccounts
core/state_transition.go Nil gaspool allowed; return gas via GasPool.ReturnGas; burn-log hook
core/state_processor.go Receipt cumulative gas via GasPool; ApplyTransaction signature
core/state_prefetcher.go GasPool API updates
core/state_prefetcher_intermediate_root_test.go GasPool API updates
core/rawdb/table.go Batch.Close passthrough
core/rawdb/freezer.go Track head vs tail; tail-over-head handling
core/rawdb/freezer_utils.go Atomic rename + reset helper; spelling fix
core/rawdb/freezer_utils_windows.go Windows syncDir no-op
core/rawdb/freezer_utils_unix.go Unix syncDir implementation
core/rawdb/freezer_table.go Tail truncation reset + sync refactor
core/rawdb/freezer_table_test.go Add tail-over-head randomized op + test
core/rawdb/freezer_resettable.go Align head field rename usage
core/rawdb/freezer_memory.go Tail-over-head reset behavior
core/rawdb/database.go Tighten key-length checks in inspector
core/rawdb/ancienttest/testsuite.go Add tail-over-head write test
core/parallel_state_processor.go GasPool API + prefetcher signature update
core/parallel_state_processor_review_test.go Prefetcher signature update
core/mainnet_witness_benchmark_test.go Witness/gaspool API updates
core/history/historymode.go Add postprague mode + prune-point lookup
core/genesis_test.go Update verkle genesis root expectation
core/gaspool.go New GasPool struct + APIs
core/evm.go Transfer emits EIP-7708 log under rules
core/error.go Add ErrGasLimitOverflow; remove initcode error
core/chain_makers.go GasPool API updates; triedb lifetime fix
core/blockchain_test.go Update witness constructor signature
console/console.go Allow digit ‘0’ in autocomplete parsing
consensus/bor/bor.go Prefetcher signature update
cmd/utils/flags.go Cache default to 4096; history mode string update
cmd/keeper/stubs.go Update build tags for womir
cmd/keeper/getpayload_womir.go Add WOMIR wasm input reader
cmd/keeper/getpayload_wasm.go Exclude womir from wasm build
cmd/keeper/getpayload_example.go Add legacy +build line
cmd/geth/main.go Remove mainnet cache bump logic
cmd/geth/dbcmd.go Fix remove.chain usage text
cmd/geth/chaincmd.go Extend prune-history to select mode
cmd/evm/internal/t8ntool/transaction.go Use vm initcode-size helper
cmd/evm/internal/t8ntool/execution.go GasPool API updates; remove request prefix stripping
cmd/devp2p/internal/v5test/framework.go Decode using stable remoteAddr
build/ci.go Add womir build; fix flags/dirs
accounts/abi/bind/backends/simulated.go Use NewGasPool for contract calls

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread core/gaspool.go
Comment thread triedb/pathdb/reader.go

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧞 Codegenie Review

Warning

Review incomplete. Some review or verification work did not complete. Planning also fell back to deterministic default coverage. Treat the results below as partial and consider rerunning.

⚠️ Found 3 verified issues.

Partial review: 189 hunks were not reviewed because budget was exhausted before dispatch.
Reviewed 195/386 hunks before stopping.

Coverage disclosure:

  • Budget stopped review work (token limit reached).
  • Verification incomplete for 13 candidates.
  • planner degraded; deterministic default plan used
  • go.sum: lockfile
  • semantic composition skipped; deterministic fallback used

🙋 Needs human attention:

  • Does every path that calls dialsched.inboundPending(id) in p2p/server.go guarantee a matching inboundCompleted(id) call (including error/early-return and panic paths), so pendingInbound entries cannot leak and permanently block dials to that node via checkDial's errPendingInbound?
  • Does EIP-8024's EXCHANGE immediate encoding really permit imm bytes 0x50 and 0x51 (which decodePair maps to pairs (14,16) and (14,15)), and is the missing pair (15,16) (would require imm 0x60, still rejected) intentional?
  • Does pruneHistoryCommand (cmd/geth/chaincmd.go:206) register utils.ChainHistoryFlag in its Flags list, and does utils.ChainHistoryFlag exist with name "history.chain"?
  • In this fork, is f.tail stored as an absolute (offset-inclusive) item number by repair()/validate() at open time, the same way f.head is (freezer.head.Add(offset) in NewFreezer)? If repair sets tail relative while TruncateTail stores an absolute tail, the new 'if f.head.Load() < tail { f.head.Store(tail) }' guard compares/stores mixed-basis values and could push head forward by up to offset items.
  • Once initerState reaches stateStalled, update() never re-evaluates progress (the ticker branch continues on stateStalled), so canExit() in indexIniter.run stays permanently true even if sync later resumes. Is that the intended terminal state in upstream v1.17.x?
  • Additional unresolved notes suppressed: 35

Sorry, this review is incomplete. The allotted max token limit of 8000000 (config review.maxBudgetTokens) was reached and the review has been degraded. Raise the limit for a complete review.

— codegenie v0.5.5 (58f82a9b2c) · View Workflow Job

Comment thread cmd/fetchpayload/main.go
Comment thread cmd/geth/snapshot.go
Comment thread core/state/statedb.go
Comment thread core/evm.go
Comment thread cmd/keeper/getpayload_womir.go
Comment thread core/state_transition.go
Comment thread internal/ethapi/api.go
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

This PR is stale because it has been open 21 days with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions Bot added the Stale label Sep 8, 2026
Base automatically changed from ppatil-upstream-v1.17.1 to upstream-merge-v1.17.4 September 10, 2026 04:56
pratikspatil024 added a commit that referenced this pull request Sep 10, 2026
Cascade hop 0 ahead of milestone 4/6 (#2328). Ten commits from develop.

go.sum was the only conflict and was resolved per module rather than per side:
c-kzg-4844/v2 v2.1.6 from this branch, which the merged go.mod requires, and
protoc-gen-validate v1.3.3 from develop, which follows its grpc 1.83.2. go mod
tidy reproduces exactly that split and leaves go.mod unchanged from the
auto-merge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pratikspatil024 and others added 2 commits September 10, 2026 11:34
Cascade hop 1 after milestone 3/6 (#2325) landed in the base.

Four conflicts. core/state/statedb.go and core/stateless/witness.go are the same
collision: upstream #34106 relocated witness stats into Witness, while #2180 had
built on the older placement. Resolved toward upstream's structure with #2180's
two divergences preserved -- addObjectWitness keeps the no-prefetcher branch that
captures storage proof-path nodes for the SRC goroutine, and NewWitness keeps the
header copy that the witness manager's hash matching depends on. addWitnessNodes
now forwards to AddState, whose owner parameter carries the same attribution
StateDB.witnessStats did; that field was never populated by any caller. The two
docs conflicts were append-vs-append and kept both sides.

Four call sites broke without conflicting and were fixed: the SRC fallback
NewWitness, two miner StartPrefetcher calls, and a GasPool test that predates
EIP-7778 making GasPool a struct.

Verified: build and vet clean, witness regeneration non-short 6/6 with 222/222
chained pairs, full suite 144 packages 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Consequence (2) asserted that placing the emission at the same point relative to
the balance change keeps serial and V2 BlockSTM in agreement on log order. It
does not. RecordTransfer captures LogIdx before emitEthTransferLog appends, so
the 7708 log lands at exactly s.logs[tr.LogIdx], and tryEmitTransferAt flushes
only below that boundary before emitting the 0x1010 log. Serial order is
[7708, 0x1010]; V2 is [0x1010, 7708].

The entry now records the measured behaviour, and warns that widening the flush
boundary to <= tr.LogIdx is not the fix -- pre-Amsterdam that index holds an
unrelated log, so it would reorder receipts on live mainnet.

Adds consequence (4): EmitLogsForBurnAccounts runs after the fee credit on the
V2 path and before it on the serial path, because the two engines set
noFeeBurnAndTip differently. Unreachable today, both addresses being fixed
pre-existing values.

Both surfaced by AI review on #2328, verified against the code, and tracked as
POS-3716. Neither is reachable while AmsterdamBlock is nil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread core/parallel_state_processor.go
Comment thread core/vm/instructions.go
pratikspatil024 and others added 2 commits September 15, 2026 17:15
…16 claim

The batch-16 ledger entry said V1/V2 keeping their own totalUsedGas leaves
parallel accounting untouched. That holds only pre-Amsterdam. After the fork the
serial path reports the refund-excluded gp.Used() while V2 keeps summing the
post-refund result.UsedGas, and MaxUsedGas never reaches the pdb, so V2 cannot
produce the Amsterdam figure at all. Receipts still agree; header.GasUsed does
not, and ValidateState compares exactly that -- so a block holding a refunding
tx fails V2 validation and falls back to serial, or is rejected under
enforceParallelProcessor. Producers are unaffected.

Added to the EIP-7778 fork-register row as an enable-time consequence and
tracked as POS-3717. Found by @lucca30 in review of #2328.

Also extends the EIP-7708 duplicate-log consequence with the point @cffls
raised: suppressing Bor's own transfer log is breaking for its consumers, and
the existing deprecation notice covers AddFeeTransferLog rather than the
AddTransferLog that EIP-7708 duplicates, so there is nothing to lean on.

Third Amsterdam surface in this milestone wired against the serial engine only.
The durable fix is Amsterdam coverage in the V2 fork-parity matrix, which would
have caught all three; recorded in POS-3717.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… register

Every dormant Amsterdam row now names the ticket that owns its enable-time work,
so the register and the epic point at each other. Previously only two of the five
were reachable from here, which meant a decision could be written down and still
be invisible at release planning.

Reframes the EIP-7708 duplicate-log consequence. The earlier text leaned on the
deprecation notice in core/bor_fee_log.go, which is the wrong argument twice
over: it covers AddFeeTransferLog rather than the AddTransferLog that EIP-7708
duplicates, and a code comment is not a deprecation mechanism for anyone
consuming the chain. The real constraint is that EIP-7708's log is not a superset
of Bor's -- ours carries both parties' pre- and post-balances, the standard one
carries only from, to and amount -- so removing ours costs balance-delta
consumers information they cannot recover from the replacement.

Tickets: POS-3715 (BAL and SLOTNUM gating), POS-3718 (transfer-log decision,
from @cffls on #2328), POS-3719 (initcode cap 49152 to 65536). POS-3720 collects
all five as the enablement checklist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pratikspatil024 added a commit that referenced this pull request Sep 17, 2026
Cascade hop 1 ahead of milestone 5/6 (#2337), run before #2328 merges so the
branch is review-ready the moment it does.

No conflicts. The v1.17.2 API sweep -- NewWitness gaining enableStats,
StartPrefetcher losing its stats parameter, AddState gaining an owner, GasPool
becoming a struct -- arrived already reconciled from the #2328 cascade, so none
of the call sites needed touching here.

Verified the #32919 interaction the fork register flags: opSelfdestruct6780 now
drives both the selfdestruct semantics and the EIP-7708 burn-vs-transfer choice
off IsNewContract, which is the documented intent. SelfDestruct6780 is gone from
the tree with no remaining references.

Verified: build and vet clean, full suite 144 packages 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pratikspatil024
pratikspatil024 merged commit ca9e98f into upstream-merge-v1.17.4 Sep 18, 2026
17 of 19 checks passed
@pratikspatil024
pratikspatil024 deleted the ppatil-upstream-v1.17.2 branch September 18, 2026 04:40
pratikspatil024 added a commit that referenced this pull request Sep 18, 2026
Cascade hop 0 after milestone 4/6 (#2328) landed in the base. Three commits from
develop, no conflicts.

Two are eth/downloader/whitelist fixes in a package this sync does not touch. The
third bumps the Go toolchain 1.26.5 to 1.26.8 across go.mod, cmd/keeper/go.mod,
.golangci.yml and both Dockerfiles -- version strings only, no code. Verified
against a local 1.26.8 toolchain.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pratikspatil024 added a commit that referenced this pull request Sep 18, 2026
Cascade hop 1 after #2328 merged and hop 0 brought develop into the base.

Delta-only: ten files, all from develop's three commits -- two
eth/downloader/whitelist fixes and the Go toolchain bump to 1.26.8. The v1.17.2
body was already reconciled into this branch by the pre-merge cascade, so
nothing from it needed revisiting.

Verified: build and vet clean, full suite 144 packages 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.