cl, db, execution, p2p, cmd: fix copy-paste drift defects#22165
Merged
Conversation
The Bytes4/48/64/96 copies of Hash.SetBytes kept length.Hash (32) in the crop and right-align arithmetic, so SetBytes panicked or misplaced bytes for most input lengths. Use the receiver's own length, matching Hash.SetBytes semantics (crop from the left, right-align short inputs).
…sion Two divergences from the BeaconBody sibling: the Deneb gate in EncodingSizeSSZ added ExecutionChanges a second time instead of BlobKzgCommitments, and NewBlindedBeaconBody dropped its version argument (callers had to SetVersion by hand; block_production.go does, Clone did not).
…endpoints pending_consolidations and pending_deposits were missing the version header and body field that pending_partial_withdrawals already returns; the three handlers are copies of each other. Also drop a stray tab from two error messages and make the forkchoice mock's pending getters settable for the test.
The StorageHistoryIdx arm checked the code domain's inverted index and CodeHistoryIdx checked storage's, so a targeted integrity check validated the wrong index.
startIdx-endIdx underflows; use endIdx-startIdx+1 like the historical trace worker's copy of this code.
Both branches of the IsPeerNotFoundErr check returned the same error; mirror the bodies handler and treat a vanished peer as success.
The four per-domain exec_domain_cache_put_rate gauges were set to raw counts while the aggregate sets a per-second rate; divide by the interval. Also fix mxExex*/mxCommitmentBrancg variable-name typos.
…utor The serial loop re-inlined the condition that was extracted and unit-tested for the parallel path.
SetupCobra was called with "integration", pasted from cmd/integration.
The pseudo-dupsort LastDup wrapped its error as "in FirstDup".
Near-verbatim copy of snapshotsync.SegmentsCaplin with no callers.
This was referenced Jul 2, 2026
Merged
Merged
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request fixes a set of “copy-paste drift” defects across multiple subsystems (execution, CL types/handlers, p2p sentry, db utilities, and CLI), bringing duplicated implementations back into alignment and adding regression tests where the issue is reproducible.
Changes:
- Corrects several logic/behavior defects caused by diverged duplicated code (e.g., SSZ size accounting, consensus-version headers, inverted-index integrity routing, sentry peer-not-found handling, AA bundle length logging).
- Normalizes stagedsync metrics naming/units and reduces drift by reusing shared logic (
shouldMarkExhaustedAtBlock). - Adds targeted regression tests for the previously broken behaviors and removes dead/unused code.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| p2p/sentry/sentry_multi_client/sentry_multi_client.go | Ignore “peer not found” when sending header response (aligns with other handlers). |
| execution/stagedsync/exec3_serial.go | Reuses shared exhaustion predicate to avoid drift from parallel executor logic. |
| execution/stagedsync/exec3_metrics.go | Fixes metric var typos and makes per-domain put gauges consistent with rate units. |
| execution/exec/txtask.go | Fixes AA bundle log length calculation to avoid underflow/misreporting. |
| db/state/integrity.go | Corrects domain routing for Storage/Code history inverted-index integrity checks. |
| db/snapshotsync/freezeblocks/block_snapshots.go | Removes dead SegmentsCaplin duplicate implementation. |
| db/kv/mdbx/kv_mdbx.go | Fixes incorrect error context string in LastDup. |
| common/bytesn_test.go | Adds regression coverage for BytesN.SetBytes semantics. |
| common/bytes96.go | Fixes Bytes96.SetBytes cropping/alignment to match Hash.SetBytes semantics. |
| common/bytes64.go | Fixes Bytes64.SetBytes cropping/alignment to match Hash.SetBytes semantics. |
| common/bytes48.go | Fixes Bytes48.SetBytes cropping/alignment to match Hash.SetBytes semantics. |
| common/bytes4.go | Fixes Bytes4.SetBytes cropping/alignment to match Hash.SetBytes semantics. |
| cmd/txpool/main.go | Fixes logger prefix to txpool (was incorrectly integration). |
| cl/phase1/forkchoice/mock_services/forkchoice_mock.go | Makes pending-queue getters mockable via stored maps for handler tests. |
| cl/cltypes/beacon_block_blinded.go | Fixes constructor version propagation and Deneb SSZ size accounting for BlobKzgCommitments. |
| cl/cltypes/beacon_block_blinded_test.go | Adds regression test for EncodingSizeSSZ tracking true encoding deltas. |
| cl/beacon/handler/states.go | Ensures pending queue endpoints set Eth-Consensus-Version header and response version consistently. |
| cl/beacon/handler/states_test.go | Adds regression test asserting consensus-version header is set across all pending queue endpoints. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced Jul 2, 2026
Draft
This was referenced Jul 2, 2026
pull Bot
pushed a commit
to Dustin4444/erigon
that referenced
this pull request
Jul 3, 2026
`bytes48.go` and `bytes96.go` were byte-identical whole files modulo the type name; `bytes4.go`, `bytes64.go`, `hash.go`, and `address.go` repeated most of the same method bodies. Since Go can't parameterize `[N]byte` by length and these types must stay comparable arrays, the bodies move to unexported helpers over `[]byte` (`fixedFormat`, `fixedSetBytes`, `fixedTerminalString`, `fixedGenerate`); each method becomes a one-liner passing `b[:]`. Net −169 production lines; no exported API change. Kept bespoke on purpose: `Address`'s EIP-55 checksummed `Hex`/`String`/`Format`; `Bytes4.TerminalString` (`%x` of the whole array — head…tail would overlap at N=4); `Hash.Generate` (`math/rand/v2`, incompatible with the v1 quick-check helper); all Hash/Address-only methods. Safety net: `TestFixedBytesGolden` (+377 lines) pins per type — every Format verb incl. bad-verb labels, String/Hex/MarshalText/Value, TerminalString, SetBytes placement, UnmarshalText/JSON error strings (incl. the `BLSSignature` label), seeded `Generate`, and the EIP-55 canonical example for Address. Goldens were captured from the pre-refactor implementation and stay green through the refactor. First commit is a cherry-pick of the `SetBytes` fix from erigontech#22165 (this consolidation builds on it); it will drop out on rebase once that PR merges. Verified: `go test ./common/...`, `go build ./...`, scoped `golangci-lint` clean (×2), `make erigon`. Part of a dedup series; siblings erigontech#22165–erigontech#22172. --------- Co-authored-by: awskii <artem.tsskiy@gmail.com>
…-fixes # Conflicts: # common/bytes4.go # common/bytes48.go # common/bytes64.go # common/bytes96.go # common/bytesn_test.go
Sahil-4555
pushed a commit
to Sahil-4555/erigon
that referenced
this pull request
Jul 3, 2026
…ontech#22168) The five `GetOrCreate{Histogram,Counter,Gauge,SummaryExt,GaugeVec}` methods repeated the same ~32-line double-checked-locking block; each copy differed only in the constructor and type assertion. They collapse onto `getOrCreate[T prometheus.Metric]` / `getOrCreateVec[T prometheus.Collector]`, and each method is now a 3-liner. The GaugeVec copy is where clone mutation had gone wrong: its type guard compared `reflect.TypeFor[*prometheus.GaugeVec]()` to itself — always false, i.e. dead (and unreachable while `namedMetricVec.metric` was concretely typed `*prometheus.GaugeVec`). The generic widens the field to `prometheus.Collector` and performs a real assertion with the same error shape as the scalar family (`TestSetGetOrCreateGaugeVecWrongType`). `registerMetricVec` is removed: its re-check-and-insert was a duplicate of the inline double-checked insert. First commit adds characterization tests (+127 lines) pinning existing GetOrCreate* behavior — same-instance returns, wrong-type errors, describe-once semantics — green against the old code before the refactor. **Update (third commit):** `getOrCreate`/`getOrCreateVec` were themselves clones differing only in which registry (`m`/`a` vs `vecs`/`av`) they touched. They now delegate to a single `getOrCreateIn` over a shared `namedEntry[M]` entry type (`namedMetric`/`namedMetricVec` become type aliases), with the wrappers widening `T` through an adapter closure so the store stays compile-time safe. The double-checked locking becomes one critical section: the fast path took the same mutex anyway, and the create funcs are pure `parseMetric` + constructor calls, so creating under the lock eliminates the create-twice-drop-loser race. The unlock is deferred because prometheus constructors can panic on inputs reachable through the public API (a `quantile`/`le` const label, a negative summary window); a non-deferred unlock would strand the set's mutex. Also drops the dead scalar `namedMetric.isAux` — never assigned, so the `ListMetricNames` filter on it was unreachable. Net −169 lines in set.go. Verified: package tests incl. `-race`, `make lint` clean, full `go build ./...`. Part of a dedup series; siblings erigontech#22165, erigontech#22166, erigontech#22167.
pull Bot
pushed a commit
to Dustin4444/erigon
that referenced
this pull request
Jul 3, 2026
… resource handlers (erigontech#22169) The package carried two parallel MCP servers — `ErigonMCPServer` (in-process typed APIs) and `StandaloneMCPServer` (JSON-RPC proxy) — with independently maintained copies of the tool catalog (~330 lines each, 264 of 270 non-blank registration lines identical), the prompts (136 lines byte-identical), the resource registration, and the log-file handlers. The copies had already drifted the worst way possible: the in-process resource handlers were still placeholders (raw URI used as the address, hardcoded `"syncing": false` and `"status": "success"`) while the standalone copies had the real logic. Two commits: 1. **Implement the in-process resource handlers** (TDD: failing tests first) — real address extraction via a shared `extractURIParam`, real `eth_syncing`, receipt-status derivation, mirroring the standalone behavior through the typed APIs. 2. **Share the registration surfaces** — one `toolSpecs()` table consumed via per-server `toolHandlers()` maps (`registerTools` panics on any catalog/handler mismatch); `registerPrompts`/`registerResources` as free functions over per-server handler sets; the four log handlers folded into a `logTools` struct embedded by both servers (also deduping the log-file-resolution switch that was inlined 4×). `eth_getStorageValues` stays embedded-only. `TestEmbeddedAndStandaloneCatalogsMatch` pins both servers to identical tool/prompt/resource catalogs so they cannot drift silently again. Net: −248 lines despite +~130 of new tests; standalone.go alone went 1724 → 1129 lines. Verified: package tests, scoped `golangci-lint` clean (×2), `make erigon`. Part of a dedup series; siblings erigontech#22165–erigontech#22168.
pull Bot
pushed a commit
to Dustin4444/erigon
that referenced
this pull request
Jul 3, 2026
…erigontech#22171) `cmd/downloader`, `txnprovider/txpool`, `node/privateapi`, and `p2p/sentry` each re-inlined the interceptor/keepalive option block that `grpcutil.NewServer` already builds — two of them complete with its dead commented-out metrics hooks — and all four repeated the same listen + health-server + serve-goroutine tail. `NewServer(rateLimit, creds)` now delegates to a new `NewServerWithOpts(creds, extraOpts...)` (nil-safe creds, no forced `MaxConcurrentStreams`), and `StartServer`/`StartServerOnListener` own the listen/health/serve tail. The four sites convert onto these. Option preservation was the review focus, per site: downloader and txpool still run **without** `MaxConcurrentStreams` (as before); txpool keeps its explicit `ReadBufferSize(0)`/`WriteBufferSize(0)`; privateapi/sentry keep health registration gated on their `healthCheck` flag while downloader/txpool keep it unconditional; existing `NewServer` callers see byte-identical behavior. Two deliberate exceptions to strict preservation: - Both converted `StartGrpc`s now take `credentials.TransportCredentials` by value (as `privateapi.StartGrpc` already does) instead of pointer-to-interface, dropping the identical unwrap shim at each site; their sole callers pass literal `nil` and are unchanged. - The txpool serve-failure log now reads `txpool gRPC server fail` instead of the `private RPC server fail` string copy-pasted from privateapi — in the standalone txpool daemon, `--private.api.addr` names the remote node it connects to, so the old label pointed triage at the wrong process. Nothing greps or asserts these strings. Otherwise no behavior change — existing tests are the safety net (txpool, privateapi, sentry suites green). Full `make lint` clean, `make erigon integration` build. Net −117 lines. Part of a dedup series; siblings erigontech#22165–erigontech#22170.
pull Bot
pushed a commit
to Dustin4444/erigon
that referenced
this pull request
Jul 4, 2026
Helper extractions collapsing the package's most-repeated scaffolds. Behavior-preserving with the compat quirks kept byte-identical, except two deliberate changes called out below. 1. **Txn lookup + index derivation ×8** — two helpers rather than one bundle, because two sites must keep their inline bor fallbacks (`GetTransactionReceipt` runs its prune/index checks with the pre-fallback block number — live pruned-bor-node behavior; debug `GetRawTransaction` early-returns on `!ok` before its bor branch). `txnLookupWithBorFallback` covers the four sites whose fallback triggers on a missed lookup — the miss contract of both `TxnLookup` implementations is verified `(0,0,false,nil)`, and block 0 has no txns, so `GetTransactionByHash`'s historical `blockNum==0` trigger is equivalent to `!ok`. `txnIndexInBlock` owns the txNum→index math at all 8 sites with the exact underflow error, called at each site's original position so error precedence is unchanged; for bor state-sync txns it returns the established `-1` sentinel (the value the block readers guard and trace_filtering decodes). 2. **`getReceiptsWithBor` ×3** — returns `(receipts, borReceipt)` rather than appending (appending would break the marshal loops' `Transactions()[TransactionIndex]`); per-site marshal flags (`withBlockTimestamp` etc.) stay exact. Its events→`GenerateBorReceipt` tail is `borReceiptForBlock`, also reused by `GetTransactionReceipt`'s bor state-sync path (nil receipt ⇔ zero events — `GenerateBorReceipt` never returns `(nil, nil)` — mapped back to that site's "tx not found"). 3. **Log range resolution** — erigon_receipts' byte-identical latest-only pair extracted into `logRangeLatestOnly`, with its FromBlock/ToBlock twin blocks collapsed into `resolveLogBound` (the begin=0-on-latest quirk lives in the per-bound default); overlay's `getBeginEnd` promoted to `BaseAPI.resolveLogsRange` with a `checkFuture` flag (eth_getLogs keeps its inline into-the-future rejections — deferring them would change which error surfaces). The two variants are deliberately NOT merged. 4. **`subscribeRPC[T]` ×5** in eth_filters — the full guard/CreateSubscription/LogPanic-goroutine/unsubscribe/select skeleton, checking channel closure before notify; notify callbacks receive a pre-bound `emit` func so the Notify+Warn boilerplate lives once in the skeleton (all call sites used the identical warn message). `NewPendingTransactionsWithBody` delegates to the same core as `NewPendingTransactions` (the only deltas are fullTx and channel buffer 256 vs 512 — both parameterized). 5. **Replay-env helpers** — the inline BLOCKHASH closures reuse the pre-existing `transactions.MakeBlockHashProvider` instead of gaining a new helper (safe: both `CanonicalHash` impls return the zero hash on miss; where a timeout applies, the provider binds the deadline-carrying ctx so hash lookups run under the EVM deadline); `validateBundles` ×2 (pinned by `TestCallManyEmptyBundles` for both callers); `setupEVMTimeout` ×6 (CallBundle, CallMany, overlay `replayBlock`, `simulateCall`, trace_call, trace_rawTransaction), returning the deadline ctx, a `store` func for the current EVM, and a cleanup that preserves the stop-before-cancel order. The trace doCallBlock/doCall stacks and trace_filtering's parallel per-tx tracer keep their own shapes — different cancellation mechanisms (cooperative ctx checks; many concurrent EVMs). Two deliberate behavior changes: - The canonical-hash-miss log line is unified on the shared provider at Debug (message `[evm] canonical hash not found`): the four jsonrpc sites keep their historical Debug level, and the `eth_simulateV1` path drops from Error — the miss is user-triggerable (e.g. `eth_callMany` bundles advance `BlockNumber` past head, so BLOCKHASH near the simulated boundary legitimately misses), geth logs nothing there, and genuine read errors still propagate to the RPC response. - EVM-timeout cancellation is now airtight: `setupEVMTimeout`'s `store` re-checks `ctx.Err()` after every store, so a deadline or client disconnect firing before — or between — EVM (re)creations still cancels the current instance (previously CallBundle/CallMany could drop a one-shot cancellation that fired between loop iterations, leaving the call running with no timeout). Pinned by `TestSetupEVMTimeoutCancelsEVMStoredAfterExpiry`, verified red against a plain store. New tests: `TestGetRawReceipts` (previously untested debug site), `TestOverlayGetBeginEnd` (previously untested overlay path), a guard-behavior test across all five subscription methods, `TestCallManyEmptyBundles`, and the timeout test above. Every pinning test was run green against the unconverted code first. Net ≈ −284 production lines, +174 of tests. Verified: `go test ./rpc/...` green (plus a `-race` pass over the timeout-helper tests), scoped `golangci-lint` clean (×2), full `make lint` clean, `make erigon`. Part of a dedup series; siblings erigontech#22165–erigontech#22179.
Sahil-4555
pushed a commit
to Sahil-4555/erigon
that referenced
this pull request
Jul 7, 2026
…rplate with generics (erigontech#22166) The sentry multiplexer repeated the same errgroup fan-out/collect scaffold in 16 methods (~350 duplicated lines), and `node/direct` carried two hand-monomorphized copies of libsentry's own generic stream adapters. This collapses both: - `fanOut[R]` — protocol-gated concurrent call with a mutex-guarded collect that can cancel the group; `fanOutSuccess[R]` — the GetSuccess OR-reduction used by the four peer-admin methods; `streamFanIn[T,S]` — the Messages/PeerEvents stream fan-in. - `StreamReply`/`SentryStreamS[T]`/`SentryStreamC[T]` moved to `libsentry/stream.go`; the `SentryMessagesStream*`/`SentryPeersStream*` copies in `node/direct/sentry_client.go` are deleted (no external references). - Before refactoring, a characterization test pins the any-client-success semantics of AddPeer/RemovePeer/AddTrustedPeer/RemoveTrustedPeer (16 subtests), green against the old code first. Preserved deliberately: `PeerById`'s errFound early-stop, `SetStatus`/`peersByClient` protocol gating, `HandShake`'s per-client protocol caching and max-reduction, and `SendMessageByMinBlock` stays serial (untouched, along with the other send-path methods). Net −218 lines including +99 of new tests. Verified: `go test ./p2p/sentry/... ./node/direct/...` plus `-race` on the sentry packages, scoped `golangci-lint` clean (×2), `make erigon`. Part of a dedup series; sibling defect fixes in erigontech#22165.
AskAlexSharov
approved these changes
Jul 8, 2026
Sahil-4555
pushed a commit
to Sahil-4555/erigon
that referenced
this pull request
Jul 8, 2026
…ities (erigontech#22170) Four independent consolidations of copy-pasted utility code, plus review follow-ups: 1. **bufio pools ×4 → `db/bufiopool`.** `getBufioWriter/putBufioWriter` (+reader twins in two of them) were byte-identical — including comments — in `db/etl`, `db/recsplit`, `db/seg`, and `db/datastruct/btindex`. One package now owns them; 512KB size and Reset(nil)-before-Put semantics preserved verbatim. 2. **keccak pools ×2 → one.** `common/hasher.go` and `common/crypto/crypto.go` each pooled `keccak.NewFastKeccak()`. The single pool of raw `KeccakState` lives in `common` (import direction forces it); `crypto.NewKeccakState`/`ReturnToPool` delegate. Reset-on-Get semantics identical on both old paths; no exported signature changed. The no-longer-pooled `Hasher` wrapper is free in practice: `NewHasher` now inlines (the old pooled version exceeded the inlining budget) and `&Hasher{}` does not escape at any call site, so no per-call heap allocation appeared. 3. **bytes.Buffer pools ×8 → `common/pool`.** Eight private `sync.Pool{New: …&bytes.Buffer{}}` copies across cl/persistence, cl/antiquary, db/snapshotsync, execution/types, and node/rpcstack (gzip responses) replaced by `GetBuffer`/`PutBuffer`; Put drops buffers over 1MB so one oversized use can't pin memory (the rpcstack copy already used exactly this cap; the others had none). Call sites that routinely exceed 1MB on mainnet no longer use a pool at all: the CL read paths (historical-states dumps/diffs, beacon-block decompression) only wrapped an in-memory slice to read it back and now feed `bytes.NewReader` straight to the zstd reader — zero-copy, cheaper than the old uncapped pools, which copied the whole blob per call — and the antiquary's multi-MB diff writer reuses the collector-owned buffer like its sibling helpers. The pool's remaining users are typically-sub-1MB write targets. Reset-on-get and drop-oversized semantics are unit-tested; a dead `plainBytesBufferPool` in base_encoding removed along the way. 4. **rpc/requests: retryConnects → cenkalti/backoff/v4** (already a dependency). Per-attempt 500ms and overall 20s budgets and dial-error propagation preserved, pinned by characterization tests written and run green against the old implementation first. Two error-swallowing bugs fixed on top, pinned by red-first tests: overall-deadline expiry after only per-attempt timeouts now returns `context.DeadlineExceeded` instead of nil (callers used to see success with an unpopulated result); and on overall-deadline expiry the last dial error is substituted only for the context's own deadline error, never for a permanent error that merely wraps `DeadlineExceeded`. Because `backoff.Retry` surfaces the overall context's error verbatim when it gives up, the substitution keys off `err == context.DeadlineExceeded` (identity) rather than `errors.Is`, so a `backoff.Permanent` error that wraps `DeadlineExceeded` is left intact. Net −146 production lines plus +180 of tests. Re-verified after merging latest `main`: `go test` on every touched tree, `make lint` clean, `go build ./...`, `make erigon integration`. Part of a dedup series; siblings erigontech#22165–erigontech#22169.
pull Bot
pushed a commit
to Dustin4444/erigon
that referenced
this pull request
Jul 8, 2026
…ts (erigontech#22172) The two caplin snapshot containers (`freezeblocks.CaplinSnapshots`, `snapshotsync.CaplinStateSnapshots`) re-implemented `RoSnapshots`' OpenList machinery — the find-open-segment walk, the optimistic-open error dance (duplicated *twice more* inline across `CaplinSnapshots.OpenList`'s two identical switch arms), and `closeWhatNotInList`. The copies had drifted in unsafe ways, which is the real payoff here: - `CaplinSnapshots`' close path called the embedded `Decompressor.Close()` instead of `DirtySegment.close()`, so **recsplit index handles leaked** on every file-list change; - stale unopened stubs (`Decompressor == nil`) were skipped rather than removed; to make that safe, `CaplinStateSnapshots` now derives the protect-list name from its `filePath` field instead of the promoted `Decompressor.FilePath()`, which would nil-panic on such a stub (pinned by `TestCaplinStateCloseWhatNotInListDropsUnopenedStub`); - both caplin close paths now inherit the generic **refcount guard** (don't close a segment a live `View`/`RoTx` still references; contract pinned by `TestCloseAndDropNotProtected`). Caveat: the guard is inert for the caplin containers today — they mark every segment `frozen`, and `VisibleSegments.BeginRo` doesn't refcount frozen segments — so this is future-proofing rather than an active fix, and the pre-existing close-under-live-view hazard for frozen segments is unchanged by this PR. This extracts `FindOpenSegment` / `ClassifyOpenErr` / `CloseSegmentsNotInList` in snapshotsync, converts `RoSnapshots` and both caplin containers onto them, collapses the two identical switch arms into one loop, and deletes the vestigial `processed` flag with its stray "Only bob sidecars count" comment (semantics preserved: `segmentsMax` still tracks BeaconBlocks only in `CaplinSnapshots`; `CaplinStateSnapshots` tracked it for every file and still does). Deliberately out of scope: making the caplin containers embed `RoSnapshots` wholesale; un-freezing caplin segments so the refcount guard actually engages for their views (a refcount-contention trade-off deserving its own PR). Behavior changes (all safety-directional, called out above): full index+seg close, stub removal (incl. the nil-panic fix), refcount guard on caplin close paths (inert today). Everything else is behavior-preserving; snapshotsync/freezeblocks suites green, scoped `golangci-lint` clean (×2), `make erigon` builds. Net −120 lines of non-test code (−50 including the two new tests). Part of a dedup series; siblings erigontech#22165–erigontech#22171.
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.
Fixes eleven defects that all share one root cause: code duplicated between siblings and then patched or mutated in only one copy. Found during a whole-repo duplication audit; each fix is surgical and independent. (A twelfth —
Bytes4/48/64/96.SetByteskeepinglength.Hashfrom theHash.SetBytesoriginal — was absorbed by the shared-helper refactor in #22173 and is no longer part of this diff.)With regression tests (written first, red → green):
BlindedBeaconBody.EncodingSizeSSZcountedExecutionChangestwice and neverBlobKzgCommitments;NewBlindedBeaconBodydropped itsversionargument (Version: 0), unlikeNewBeaconBody—block_production.gowas already working around it with an explicitSetVersion(TestBlindedBeaconBodyEncodingSizeTracksEncoding).pending_{consolidations,deposits,partial_withdrawals}endpoints only the third setEth-Consensus-Version/version; now all three do (TestGetPendingQueuesConsensusVersionHeader; forkchoice mock's pending getters made settable for it).Without new tests (log/metric/dead-code corrections, or not reasonably reproducible as a unit test — noted per item):
IntegrityInvertedIndexAllValuesAreInRangehad theStorageHistoryIdx/CodeHistoryIdxarms crossed, so a targetederigon seg integritycheck validated the other domain's inverted index. A red repro test would need a corrupt-II fixture; the fix is a label/index correction verifiable by inspection.startIdx-endIdx(uint64 underflow); the historical-trace copy of the same code already had the correct form.exec_domain_cache_put_rategauges were set to raw counts while the aggregate sets a per-second rate — dashboards mixing them compared different units; alsomxExex*/mxCommitmentBrancg*variable typos, and the serial executor re-inlined the extracted-and-testedshouldMarkExhaustedAtBlockinstead of calling it (behavior identical:(!a || b) ≡ (a → b)).getBlockHeaders66returned the same error on both branches of itsIsPeerNotFoundErrcheck; a peer disconnecting mid-answer now returns nil like the bodies/BAL handlers."integration"prefix, pasted from cmd/integration.LastDupwrapped errors as"in FirstDup".SegmentsCaplin, a dead near-verbatim copy ofsnapshotsync.SegmentsCaplinwith zero callers.Verification: affected-package tests green, scoped
golangci-lintclean (×2),make erigon integrationbuilds.