core/vm, params, eth: merge geth v1.17.5 (v1.17.5 sync) - #2354
Draft
pratikspatil024 wants to merge 118 commits into
Draft
core/vm, params, eth: merge geth v1.17.5 (v1.17.5 sync)#2354pratikspatil024 wants to merge 118 commits into
pratikspatil024 wants to merge 118 commits into
Conversation
This PR drops support for v0 blob sidecar in blobpool. Since the osaka fork activation time has passed, these code paths are now unused. It is assumed that only v1 transactions exist in the blobpool.
This PR inlines the gas deduction by getting rid of the tracer and use `chargeRegularOnly` for the non-state opcode. It fixes a performance regression introduced by EIP-8037 PR. ``` throughput MGas/s | 184.4 (±0.3%) | 193.1 (±1.0%) | +4.7% ▲ -- | -- | -- | -- mean newPayload | 164.2 ms (±0.3%) | 156.9 ms (±1.0%) | -4.5% ▲ p50 newPayload | 154.6 ms (±0.1%) | 147.6 ms (±0.7%) | -4.5% ▲ p95 newPayload | 273.3 ms (±2.3%) | 261.6 ms (±2.4%) | -4.3% ≈ noise p99 newPayload | 403.6 ms (±4.4%) | 380.9 ms (±4.0%) | -5.6% ≈ noise ```
Mirror the guard applied to (*UDPv4).Dial in #34916: when the target node has no usable UDP endpoint, return errNoUDPEndpoint instead of silently sending the ENRRequest to an invalid AddrPort and waiting for a timeout. The other UDPEndpoint-using request paths in this file already do this: ping v4_udp.go:215 errNoUDPEndpoint Ping v4_udp.go:228 errNoUDPEndpoint newLookup v4_udp.go:309 errNoUDPEndpoint RequestENR v4_udp.go:358 addr, _ := n.UDPEndpoint() <-- outlier RequestENR is reachable from external callers like cmd/devp2p/crawl.go, which feeds in arbitrary nodes that may not have a UDP port set. Before this change, such nodes burn one full RPC timeout; after it, the caller gets a clean error immediately. The added test fails on master with "RPC timeout" and the trace logs "PING/v4 addr=invalid AddrPort", confirming packets are being written to an unspecified address; with the fix it returns errNoUDPEndpoint without doing any I/O.
This PR adds the support of Pebble v2, details as below: - Pebble V2 will be used if database is empty - Pebble V1 will be used if database is not empty and the format is old - Upgrade command (geth db pebble-upgrade) is provided to upgrade the format to v2 offline
When ancient history is pruned, geth serves old block bodies and receipts back from era files on disk. Until now that fallback only worked for .era1 files (pre-merge), so requests for post-merge blocks backed by .ere files failed even though the data was present. This PR generalizes the era store to open both formats. --------- Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
…es (#34772)
Replace 1-byte-per-bit path encoding with bit-packed `BitArray`,
reducing DB key size by 8x
Benchmark (sparse single-leaf write, M3 Pro):
```
│ Before (1B/bit) │ After (BitArray) │
│ sec/op │ sec/op vs base │
CollectNodesSparseWrite-11 10.50µ ± 1% 9.78µ ± 1% -6.86%
│ B/op │ B/op vs base │
CollectNodesSparseWrite-11 5.50Ki ± 0% 5.09Ki ± 0% -7.38%
│ allocs/op │ allocs vs base │
CollectNodesSparseWrite-11 67 ± 0% 58 ± 0% -13.43%
```
---------
Co-authored-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
Implements spec change ethereum/EIPs#11807 This PR resolves the conflict between the EIP-7928 and EIP-8037. Specifically in contract deployment, EIP-7928 requires to not resolve the deployed account until it's accessed, while in EIP-8037, the early access is required to determine if the account-creation should be charged or not. This PR addresses this conflict by changing the EIP-8037 a bit, unconditionally charge the account creation in CREATE Family (CreateTx, Create/Create2 opcode) and refunds the associated gas cost if the account creation doesn't happen ultimately. Checkout https://hackmd.io/@bFEBbZiVSAO0IURh9qzEFg/BJmFYqCeGl for more details What's more, now the LIFO mechanism is used for refilling the state cost in frame revert, frame halt, state opcode refunds.
This PR improves the block download used by snap sync. Specifically, blocks and their associated data (receipts and canonical hash mappings) are now written directly to the database without checking existence. The current implementation could fail in cases where the block header and body were already present (has.Block returns true), but the corresponding canonical hash mapping was missing. One possible scenario is when a newPayload event is processed without a subsequent forkChoiceUpdate. It is still unclear why Geth may re-enter snap sync after Engine API events have been processed after the sync. Anyway, bypassing the existence is a reasonable change. What's more, in the downloader, the presence of canonical hash is also considered for deciding the range of blocks to be downloaded. Specifically: - in the full sync, the block with header and body available but canonical hash missing will be re-inserted; - in the snap sync, the block with header, body and receipt available but canonical hash missing will be re-inserted;
This PR addresses the panic in tests. As the eventLoop is spun up when
the downloader was closed, the sub will be nil and make the panic
happens.
```
goroutine 421 [running]:
github.com/ethereum/go-ethereum/eth/downloader.(*DownloaderAPI).eventLoop(0xcb0e4d0)
/opt/actions-runner/_work/go-ethereum/go-ethereum/eth/downloader/api.go:91 +0x127
created by github.com/ethereum/go-ethereum/eth/downloader.NewDownloaderAPI in goroutine 352
/opt/actions-runner/_work/go-ethereum/go-ethereum/eth/downloader/api.go:50 +0xf2
```
implements https://github.com/ethereum/EIPs/pull/11760/changes#diff-0c9428673c7c725120dae93fda8a181c38bcfb1759d45e8accaf73b14e1f35cb --------- Co-authored-by: Gary Rong <garyrong0905@gmail.com>
## Summary - Release the storage iterator after iterating slots in `geth snapshot dump`, matching the existing account iterator cleanup. ## Test plan - [x] `go build ./cmd/geth/...` - [ ] Manual: run `geth snapshot dump` on a node with storage data and verify output is unchanged
Implements https://eips.ethereum.org/EIPS/eip-2780 --------- Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
This feature is an optimization used in the BAL, mostly for experimental purpose. --------- Co-authored-by: jwasinger <j-wasinger@hotmail.com> Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de>
…5250) listEIP7610EligibleAccounts opens an account iterator and never releases it.
`devp2p discv4 listen` / `discv5 listen` is the supported replacement for the removed bootnode tool, but it bound IPv4-only and `-extaddr` took a single address, so it couldn't run a dual-stack bootnode. This binds the listener dual-stack (falling back to IPv4-only where IPv6 is unavailable) and lets `-extaddr` take a comma-separated IPv4/IPv6 pair. A single node can then advertise both `ip` and `ip6` in its ENR over one UDP port: ``` devp2p discv4 listen --nodekey <key> --addr [::]:30301 \ --extaddr 203.0.113.10:30301,[2001:db8::1]:30301 ``` The fallback IP is only derived from the listener when no `-extaddr` is given, so a v4- or v6-only `-extaddr` no longer leaks a loopback entry. All addresses must share one UDP port (single socket).
EIP: https://eips.ethereum.org/EIPS/eip-8246 Supersedes #35218
Clone the existing terminal handler attrs before appending new attrs. This avoids a potential attr memory overwrite when append reuses the backing array shared with the parent handler.
…bles (#35258) This PR is related to the recent bug reported in #35210. While trying to reproduce the error, I found that when the head state is missing (e.g. unclean shutdown), we attempt to truncate the head to the most recent block with state across all chain freezer tables. However, for newly added tables such as the bal table, both the head and tail are initialized to the minimum head of the existing chain freezer tables. As a result, the `truncateHead` fails with the “truncate below tail” error. This PR fixes the issue by resetting newly added empty tables with `items` as the tail when `truncateHead(items)` is called on them.
This PR adds blobTxForPool migration support in limbo. Previously, there was no conversion path from limbo entries containing types.Transaction. Now that we have the new blobTxForPool type, this PR adds migration logic between both types. New test code (limbo_test.go) to test this conversion is added. --------- Co-authored-by: Felix Lange <fjl@twurst.com>
This PR parallelizes the block validation alongside the IntermediateRoot, saving the time spent on the receiptRoot hashing, BAL hashing and so on.
The deep-reorg check used depth >= maxReorgDepth, rejecting reorgs at exactly the configured limit. Use > so a depth equal to maxReorgDepth is still accepted.
This PR coordinates the prefetcher with the main tx executor. Block processing publishes the index of the transaction it is executing, prefetch workers skip anything already reached and transactions above 1M gas are promoted to the front of the prefetch queue while the rest keeps block order.
commitPivotBlock updated committed without pivotLock, while other pivot transitions serialize through that lock. Take the lock around the store to keep pivot commitment consistent with pivotHeader updates.
This PR fixes the incorrect size calculation for blob sidecar. The original formula is for legacy sidecar without the version tag. As the legacy version has been deprecated and no longer supported by the Geth's blobPool, the size calculation should also be flipped to sidecar v1.
This PR updates the go-snappy dependency.
Twenty upstream first-parent commits, `v1.17.4..04bf045`. Thirty conflicted paths, and eleven further breaks that git reported as clean merges — the conflicts were the cheap part of this batch. Hardfork and consensus surfaces. EIP-7954 moves MaxCodeSizeAmsterdam from 32768 to 65536. Dormant: bor's live cap is MaxCodeSizePostAhmedabad, reached through the Ahmedabad gate, and Amsterdam is nil on every preset. It does change the enable-time delta, though — activating Amsterdam would now double the contract size limit rather than leave it unchanged, which is a product decision and is recorded as one. EIP-8282 arrives entangled with the block-access-list construction cluster declined during the v1.17.4 sync: upstream's PostExecution returns three values and its helpers take rules and a construction list, where bor's take neither. Neither side-pick was right, since keeping ours drops a new EIP and taking theirs re-adopts the declined cluster sideways. The EIP is wired dormant in bor's own shape instead, mirroring the existing withdrawal and consolidation queue wrappers, behind bor's block-based Amsterdam gate. EIP-8246 removes the SELFDESTRUCT self-burn under Amsterdam, so the residual burn-log pass and its log type are deleted upstream. All of those removals landed cleanly, but bor also carried a parallel-executor twin of the burn-log function that upstream cannot see, which survived as dead code still calling the deleted log constructor. Removing it keeps the two executors in lockstep: the sole call site dispatched through the vm.StateDB interface and served both. The state-prefetch fix for absent accounts turned out to be upstream converging on bor's existing ordering, so bor's side was kept and witness behaviour is untouched. Two upstream commits were adopted as units after partial adoption proved unsafe. The snap-sync canonical-mapping fix has a detection half and a repair half that only work together; taking detection alone makes the downloader re-request a block forever while the writer keeps skipping it. Adopted in full across all four landing sites, including bor's two inlined linkage checks and its diverged writeLive, which keeps its own signature, header collection and receipt handling. The v0 blob sidecar drop was initially declined at the validation layer, which was wrong: the commit's production half had already auto-merged, leaving validation demanding v0 while the pool stored v1 only. The tests found it. Now adopted as a unit. Pebble v2 is a port rather than an adoption. Upstream keeps the old implementation alongside a version detector and makes the main file the v2 path; bor's write-path tuning and its bespoke amplification metrics live in that file and were carried across onto v2's renamed fields, verified against the module source. Half those renames were outside the conflicts and only the compiler found them. The instrumentation was deliberately not duplicated into the retained v1 implementation, so a node on a pre-v2 database format reports only upstream's basic metrics until it migrates — recorded rather than discovered later. The era store's ere-file support is declined wholesale: it imports a package bor deleted entirely, so there is no landing site. Four new upstream EIP test files are removed as coverage gaps. Each depends on either the timestamp-based Amsterdam field bor does not have or on a fixture from the declined block-access-list tests. Bor takes the EIP code without upstream's tests, and each file has a backlog row saying what re-adding it would need. Verified: build clean; full-tree vet clean apart from the two pre-existing lock-copy findings; gofmt clean; go mod tidy clean in both modules; and the touched packages all pass — pebble, params, rawdb and eradb, the txpool and its subpools, downloader, state, vm, tracers and devp2p. One failure is pre-existing and signature-matched to the baseline: an ethtest panic on a nil Bor config reached from the miner's work loop, which CI does not see because its test list filters the command packages.
Twenty upstream first-parent commits, `04bf04530..f9417bb`. Twenty-four conflicted paths and five further breaks that git reported as clean merges. Two commits dominate, and both were adopted as units because declining the conflicted files would have stranded a half that had already auto-merged. The blob schedule changes shape upstream: from Prague onward it is updated only at BPO forks, so named forks no longer declare their own configuration. Bor has no BPO forks, so adoption reduces to dropping the Osaka entry and taking the rewritten lookup. It is behaviour-neutral here, because bor's Osaka blob values were byte-identical to Prague's and the fall-through returns the same numbers; neither production network configures a blob schedule at all. The rewrite also brings a nil guard the previous switch lacked, which matters precisely because a nil schedule is bor's production case. Bor's own Verkle entry is untouched by the upstream change and is kept. The Amsterdam override flag is the quieter of the two. Its flag definition and command registration had already merged cleanly, so declining the remaining files would have shipped an option that parses, is accepted, and does nothing — no build failure and no failing test to catch it. It is wired through instead, converted to bor's block-based gate rather than upstream's timestamp. Three EIPs arrive and all merge dormant. The deterministic deployment factory auto-merged against an Amsterdam predicate bor does not have and was rewired to the block form, where "first block on which the fork is active" is the same condition. The cold storage access cost arrived as an add beside bor's own PIP-88 SLOAD helper at the same offset; both are kept, and declining was not available because its call site had already merged. The block-access-list spec change is a re-decline touching only an already-deleted test file. Elsewhere: the transaction-handler preallocation has no landing site, since the function it optimises does not exist in bor after two earlier protocol declines; the authorization-scheme change is taken verbatim despite an upstream defect, so that upstream's own fix will merge cleanly later; and a test diagnostic missing its format verbs is completed by hand where it did not auto-merge. Three more upstream EIP test files are removed as coverage gaps. Unlike the earlier ones these depend on nothing of their own — they are orphaned by helper definitions removed in the previous batch. Both of those blocking files turn out to be gated on a single line each, so one small follow-up would restore coverage for all five EIPs bor has now adopted dormant. That is recorded as one backlog entry rather than seven, and deliberately left out of this merge. Verified: build clean; full-tree vet clean apart from the two pre-existing lock-copy findings; gofmt clean; go mod tidy clean in the main module; and the touched packages all pass. Two packages fail and both were re-run at the previous batch's commit and reproduce there with identical assertions, so neither belongs to this batch; CI does not see either, because its test list filters the command packages. The previous batch's claim that the keeper module was tidy is corrected: it is not, it does not build standalone either before or after this batch, and since nothing upstream touches it here that churn is left out rather than folded into a merge commit.
Twenty upstream first-parent commits, `f9417bb27..76e3dc6`. Twenty-two conflicted paths, and three further breaks that git reported as clean merges. The one that mattered most was not in a conflict at all. Upstream decouples chain rewinding from state recovery in the path scheme, so a deep rollback is performed once at the end rather than block by block. Bor carried a stateless-node exemption around the old state check, upstream deleted that check and reintroduced its replacement further down the same function, and the replacement merged cleanly without the exemption. A stateless node holds no state by design, so it would have reached the non-genesis crash branch on any rewind and exited. The exemption is re-applied at the new site, leaving stateless behaviour exactly as it was and giving every other node the single-shot rollback. Bor's other local difference here vanished with the block that carried it. The deterministic deployment factory now runs during block building, simulation and tracing rather than during block processing alone, which is the difference between a producer and its validators agreeing on the state root at the activation block. It is adopted in bor's block-gated form, and the transition helper is retired in favour of the pre-execution path that upstream moved it to. One gap is recorded rather than closed: bor's miner does not call the shared pre-execution routine at all, inlining its own steps instead, so the fix has no landing site there. The conflicted region on bor's side is empty, and adding the step would be authoring consensus-path code rather than resolving a conflict, so it belongs with the enablement work. The block access list ordering check becomes strict, so a duplicated address is rejected as the spec requires. The helper it calls exists upstream but had been removed here once its last caller went away, so taking the one-line change alone would not have compiled; the helper is restored along with it. The access list exchange fix applies to a protocol surface this fork does not carry, and is declined accordingly; the test that arrived with it outside any conflict is removed for the same reason. A flag-parsing correction that treats an explicit false as presence is applied to this fork's own network cases too, since the neighbouring case had already merged with the new behaviour and one switch should not mix both. Verified: build clean after correcting one clean-merge break in the transition tool; full-tree vet clean apart from the two pre-existing lock-copy findings; gofmt clean; go mod tidy clean in the main module; and the touched packages all pass. Three packages fail and each was re-run at the previous batch's commit and reproduces there with an identical failure set, so none belongs to this batch. The transition tool was baselined explicitly because this batch edits it. CI sees none of the three, because its test list filters the command packages. A separate finding on a live gas-metering path was raised during this batch's twin scan and deferred to the follow-up list by decision; it is not addressed here.
Twenty upstream first-parent commits, `76e3dc6b5..6e6fcef`. Thirty-two conflicted paths, the most of this sync, resolving to its smallest diff: four upstream commits are declined whole and taken as follow-up work instead. The batch exists for the new fork stub, which lands gated off. Upstream schedules it by timestamp; this fork schedules by block, so the field, the activation helper, the rules flag, the fork-order and compatibility entries, the banner and the four virtual-machine sites are all converted to the block form used by every neighbouring fork. One of those, the compatibility entry, had merged cleanly in the timestamp form and would not have compiled. The gate is nil on all six surfaces: both sets of chain parameters, both runtime presets and both packaged genesis files. Upstream enables it from genesis on one development preset; this fork's development chain stops several forks earlier, and the new fork's instruction set derives from one it never enables, so it is left nil there too. The precompile delta against the previous fork is empty, and that was read off the stub rather than assumed: the new instruction set is the previous one with nothing enabled on top, and both precompile lookups return the previous fork's tables, so the P256 verifier is carried forward as required. This fork's own later forks are matched ahead of it in all three switches, so their precompile sets cannot be displaced. Two local guards fired on the new rules field and were worked through rather than silenced: the multi-client precompile checklist, and the classification of every fork against the serial and parallel state processors, where a stub with no state-processor branch is recorded as absent from both. Of the four declined commits, three had already merged part of themselves cleanly, so declining them file by file left the other half stranded: a whole new peer-scoring package with references bleeding into merged code, an access-list field this fork removed long ago leaving a dangling reference and unused imports, and a test-harness accessor for a field this fork's environment type does not have. Each was reverted in full instead. A fourth commit was declined only because it shares a file with two of those, and keeping its configuration half alone would have shipped a command-line flag wired to nothing. The largest decline is the intrinsic-gas and gas-budget rework, deferred by decision to its own change. It is structural rather than a specification tweak, and it quietly drops one arm of a transaction gas-limit cap that is live on both production networks. Everything in it is gated behind a fork that is disabled here, so deferring it changes no behaviour today. Two neighbouring commits that share files with it were checked against its shape, found independent, and re-applied afterwards. Also taken: a cryptography library bump, aligned across both modules and trimmed to exactly that change; refreshed builder contract addresses and bytecode, copied verbatim rather than retyped; a gas-budget cap in the execution runtime; charging the calldata floor when it exceeds regular gas; and draining oversized protocol messages before rejecting them rather than after. Verified: build clean after fixing two clean-merge breaks; full-tree vet clean apart from the two pre-existing lock-copy findings; formatting and module tidiness clean; and the touched packages all pass, including the full core suite. One package fails with the standing signature-matched panic that continuous integration does not see.
Twenty upstream first-parent commits, `6e6fcef0b..81ab8b5`. Forty-one conflicted paths, the widest set of this sync, resolving to its smallest result: eleven files. One forty-seven-file commit and five dependents are declined together. The large one implements the sparse blob pool, relaying blob cells rather than whole blobs over a new protocol version. It is declined on two independent grounds, either sufficient on its own. This fork still speaks the two older protocol versions, having declined the two intervening ones with recorded reasoning about state-sync receipt exclusion, so a third cannot precede them; and the cache file this commit extends by two hundred lines does not exist here, having been declined earlier. That makes four deferrals on the same protocol surface, and the divergence is compounding enough to deserve one deliberate decision rather than another batch-by-batch deferral. Two further commits fall with it because the only files they touch are files it creates. The new fork stub gains a correction: its instruction set now derives from the preceding fork rather than skipping back one further, which is right, since it follows that fork and should inherit its opcodes. The precompile finding recorded when the stub landed is unaffected, and was re-checked rather than assumed: the preceding fork has no precompile branch of its own and falls through to the same table the stub returns explicitly, so the two share a set and the delta between them remains empty. Six other commits are declined as consequences of earlier decisions rather than new judgements: two belong to the engine-API group already set aside, one adds an access list to the chain export format from the declined cluster, one edits a function introduced by the deferred gas-metering rework, one has no landing site because this fork's chain object holds no such cache, and one is entirely test files this fork keeps deleted. That last one also adds a new test which references a helper from a removed file, so it joins the same orphan family. A further pair is declined as twins already present: this fork implements both the garbage-collection knob and the cache-derived tuning independently, in its own command-line surface. Adopting upstream's would leave two competing knobs across two surfaces. Adopted, in this fork's shape: the snap-sync pivot is no longer advanced once it has been committed. The upstream condition also consults a helper that lives in a file renamed away here, so only the commitment guard is taken — the field already exists and the identical guard is already used elsewhere in the forked downloader, so this aligns two paths that had drifted apart. Verified: build clean after three revert rounds driven by the compiler, each one a commit whose other half had merged cleanly; full-tree vet clean apart from the two pre-existing lock-copy findings; formatting and module tidiness clean; and the touched packages all pass, including the full core, eth and miner suites. One package fails with the standing signature-matched panic that continuous integration does not see.
Ten upstream first-parent commits, `81ab8b594..9621c6a`, closing this sync. Eighteen conflicted paths resolving to ten files — the smallest batch, the only one to build on the first attempt, and the only one where no declined commit left an auto-merged half behind. The version file moves to the release value. It had merged in as an unstable snapshot at the start of this sync and was deliberately left alone until the commit that stabilises it, which is the last one in the range. The one commit needing real analysis coordinates the prefetcher with the main executor: the processor publishes the index it is executing, prefetch workers skip anything already reached, and heavy transactions are promoted to the front of the queue. An earlier batch had a case where upstream turned out to be converging on this fork's own ordering, so that was checked first. This is not that case. Both interfaces here are diverged in both directions rather than by the added parameter alone; the published index has no sound meaning against this fork's parallel executor, which runs transactions out of order and speculatively, so supplying one from the serial path only would be a silently wrong signal on the path that matters; and this fork's prefetcher is stream-based, its workers carrying arrival order rather than block position, with a second caller that has no block to sort at all. Declined whole, with the port shape recorded. Adopted, in this fork's shape: block validation now computes the derivable header fields concurrently with the state root, with this fork's existing timer moved to follow the root computation to its new site, and the extracted helper losing the parameter only the declined access-list branch used. Error precedence is unchanged. A downloader fix was applied to this fork's twin rather than to the file upstream changed, which was renamed away here long ago. The twin carried the same defect — a commitment flag stored outside the lock every neighbouring pivot transition uses — on a path that is live, and whose reader was aligned with upstream only one batch ago. The sole caller holds no lock there. Also taken: the sidecar size fix, which is version-conditional and therefore correct for both sidecar shapes even though the pool half of the same commit is declined against a shape this fork does not have; a bearer-token comparison that was case-insensitive when tested but case-sensitive when stripped; and a compression dependency bump, noting that upstream pinned an unreleased revision rather than a tagged one. Declined besides: a fetcher fix whose only file belongs to a declined feature, a reorg-depth fix from the engine-API group, the pool half of the sidecar commit, and a memory-limit guard that has nowhere to land because this fork replaced that whole configuration path with its own. The twin scan found three and resolved them three different ways — one fixed, one with nowhere to land, and one where this fork's own constant carries the same off-by-one upstream corrected. That last is left alone and written down: it changes accept and reject behaviour on a constant this fork authored, which is not something to settle on an upstream merge. Verified: build clean on the first attempt; full-tree vet clean apart from the two pre-existing lock-copy findings; formatting and module tidiness clean; the touched packages all pass, including the full core and eth suites; and the race detector was run over both the newly concurrent validation path and the changed downloader lock ordering. Three packages fail with the standing signature-matched failures that continuous integration does not see.
Documentation only; no code changes. Covers all six batches of this milestone, and with them the merge work is complete: the branch carries upstream history through the release tag, in six batches, each a single merge commit with its reasoning recorded. These four files were kept out of the tree until now on purpose, so that no merge commit carried documentation churn alongside its conflict resolutions. The milestone's weight sits in four decisions. The new stub fork was the reason the middle batch existed. Upstream schedules it by timestamp; this fork schedules by block, so the field, the activation helper, the rules flag, the ordering and compatibility entries, the banner and the four virtual-machine sites were all converted — including one compatibility entry that had merged cleanly in the timestamp form and would not have compiled. The gate is nil on all six surfaces. Its precompile delta against the preceding fork is empty, and that was read off the code twice rather than assumed once: a later batch rebased the stub's instruction set onto the preceding fork, which moved the basis the first check had been made against, so the check was repeated against the new basis. Two local guards fired on the new rules field and were worked through rather than silenced. The sparse blob pool was declined, and with it the two commits whose only files it creates. It is the fourth deferral on the same protocol surface; that compounding divergence is now written down as deserving one deliberate decision rather than a fifth deferral. The intrinsic-gas and gas-budget rework was deferred to its own change by operator decision. It is structural rather than a specification tweak, and it quietly drops one arm of a transaction gas-limit cap that is live on both production networks. Everything in it is gated behind a fork that is disabled here, so deferring it changes no behaviour today — but the ordering matters and is recorded: the same upstream change rewrote the tests that a separate deferred item wants to restore, so restoring those first would mean restoring tests for a shape this fork does not have. The prefetcher coordination was declined last, after being checked against an earlier case in this same sync where upstream turned out to be converging on this fork's own ordering. It is not that case, for three independent reasons recorded in full, and the port shape is written down rather than the refusal alone. One live-path finding was surfaced during the sync and deferred by operator decision to work on top of this milestone. It concerns the ordering of a state read against a gas guard in a storage-write cost function, is described here in neutral post-fix terms, and is tracked with the other follow-ups. Everything intentionally not adopted is in the backlog file, with what a future adoption would require. Nothing was dropped silently.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (35.09%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## ppatil-upstream-v1.17.4 #2354 +/- ##
===========================================================
- Coverage 54.96% 54.80% -0.16%
===========================================================
Files 930 934 +4
Lines 168109 169551 +1442
===========================================================
+ Hits 92393 92924 +531
- Misses 69808 70667 +859
- Partials 5908 5960 +52
... and 21 files with indirect coverage changes
🚀 New features to boost your workflow:
|
This was referenced Aug 12, 2026
core, consensus/beacon, eth: merge geth v1.17.3 batch 1/7 (v1.17.4 sync, milestone 5/6 part 1)
#2340
Draft
pebble v2's LevelMetrics.TablesSize is already int64, so the int64() conversion in the actual-data-size gauge is a no-op that golangci-lint's unconvert linter rejects. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Reviewer guide — stacked PR 12 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 → #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), andcodecov/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 indocs/upstream-merges/.Summary
Merges go-ethereum v1.17.5 into bor, continuing the upstream sync. 110
upstream first-parent commits (
v1.17.4..v1.17.5), taken in 6 batches, eacha single merge commit whose resolution reasoning is recorded in the ledger. The
upstream
v1.17.5tag (9621c6ad1) is an ancestor of this branch, so the synctarget is reached rather than approximated.
v1.17.4 and v1.17.5 ship as one stable release: this PR merges into the
v1.17.4 branch, and the base branch goes to
developonce, at the end of thewhole effort.
v1.17.4..v1.17.5, 110 first-parent commitsDocumentation lives in
docs/upstream-merges/v1.17.5/:plan.md— batch boundaries, deviations, ordered follow-upsledger.md— every resolution, per batch, with reasoningfork-register.md— per-fork/EIP dormancy verificationneeds-wiring.md— everything intentionally not adopted, and what adopting it would takeConsensus-relevant items, for the reviewer's attention first
Bogota lands dormant, in bor's block-based form. Upstream schedules it by
timestamp; bor schedules by block, so the config field, activation helper, rules
flag, fork-ordering and compatibility entries, startup banner and the four VM
sites were all converted. One compatibility entry had auto-merged in the
BogotaTimeform and would not have compiled. The gate is nil on all sixsurfaces — both
paramspresets, bothinternal/cli/server/chains/*.go, bothbuilder/files/genesis-*.json.Its precompile delta against the preceding fork is empty, and that was read
off the code twice rather than assumed once: batch 5's #35383 rebased
newBogotaInstructionSet()from Osaka onto Amsterdam, moving the basis thefirst check was made against, so the check was repeated. Bor's
activePrecompiledContractshas noIsAmsterdamcase, so Amsterdam fallsthrough to
PrecompiledContractsOsaka— exactly what the explicitIsBogotacase returns. Only the opcode basis moved.
Both bor guards fired on the new rules field and were worked through rather
than silenced:
TestReinforceMultiClientPreCompilesTest(the 5-stepmulti-client checklist) and
TestV2ForkParity(classified{inV1: false, inV2: false}).A stateless-node regression was caught outside any conflict. #35252 moved
the chain-rewind state check, and its replacement auto-merged without bor's
!bc.cfg.Statelessexemption. A stateless node would have hitlog.Crit("Chain is stateless at a non-genesis block")and exited on anyrewind. The guard was re-applied at the relocated site. git reported that file
as a clean merge.
Every upstream fork and EIP in this range is merged dormant (invariant 9),
verified per fork in
fork-register.md. Nothing here changes behaviour onmainnet or Amoy.
Executed tests
Per-batch tier, run on all six batches:
go build ./...— exit 0go vet ./...— exactly the two known pre-existing lock-copy findings(
core/parallel_state_processor.go:341,trie/secure_trie.go:88) and nothingelse
gofmtclean;go mod tidyclean in the main modulego teston every touched package, including the fullcore,ethandminersuitesAdditionally on the final batch, because it introduces a goroutine into
consensus-critical
ValidateStateand changes lock ordering in the downloader:go test -race ./core -run 'Validate|Insert|Chain|State'— cleango test -race ./eth/downloader/...— cleanPre-existing failures, re-run and signature-matched at each batch (compared
by failure text, not package name, against the previous batch's commit):
cmd/devp2p/internal/ethtest(nil-BorConfigpanic viaparams.(*BorConfig).CalculatePeriod),cmd/geth(TestAttachWelcome,TestConsoleWelcome,TestExport,TestCustomBackend,TestCustomGenesis),cmd/evm(TestT8n,TestEvmRun,TestEVMTracing,TestEvmRunRegEx). Allare invisible to CI, which excludes
cmd/viaTESTALL = $(go list ./... | grep -v go-ethereum/cmd/).Accepted-red CI checks
Quality metrics(diffguard) — skipped by operator decision. It is alsostructurally broken for stacked PRs:
--base origin/${{ github.base_ref }}resolves to the bottom of the stack, so it diffs the entire sync (~400 files)
and is SIGTERM'd at the runner limit.
by hand.
Rollout notes
gate is flipped, no activation height is set, no precompile set changes on any
live network.
a stack that ships as a single stable release.
golang/snappybump,flagged in the ledger because upstream pinned an unreleased pseudo-version
(
v1.0.1-0.20260716114414-9ae09f520e93) rather than a tagged release. It istrivially revertible if the team prefers to hold at
v1.0.0.version/version.gonow reads1.17.5/stable, matching upstream'srelease commit.
Follow-ups owed on top of this milestone
Ordered, with the dependency spelled out — the naive order is the wrong one.
Full detail in
plan.md.decision: it is a structural rework of the intrinsic-gas and gas-budget flow,
not a spec tweak, and it silently drops the
isMadhugiriarm of bor's liveEIP-7825 transaction gas cap. Dormant either way, so deferring changes no
behaviour today.
core/eip8037_test.go+core/vm/eip8037_test.go(and the fivefurther orphaned EIP test files). Blocked on (1) — #35318 rewrote those
tests, so upstream's current versions target the post-#35318 shape. Doing (1)
first makes these tests its verification.
makeGasSStoreFuncPIP88with upstream's post-#35261 ordering.Independent of (1) and (2), and on a live EVM gas path. It needs its own
review, boundary tests, and explicit sign-off because it changes a
transaction's state read set.
go mod tidyincmd/keeper. Pre-existing; wants its own small commit.Deferred, and worth one deliberate team decision
The eth-protocol surface is now four deferrals deep: eth/68-drop (#33511),
delayed decoding (#33835), eth/71 BAL, and now eth/72 sparse blobpool
(#34047) — 47 files, EIP-8070, blob cells, custody bitmap via
forkchoiceUpdatedV4,engine_getBlobsV4. eth/70 was adopted separately in#2341. This divergence compounds with each release and deserves a single
deliberate decision rather than a fifth deferral.
Also recorded: an Amsterdam-enable-time backlog in
needs-wiring.mdthatmust all land before Amsterdam is ever enabled — most notably that bor's miner
never calls
core.PreExecution, so EIP-7997 would not be applied during blockbuilding and a producer would disagree on state root with validators.