Skip to content

eth/consensus : implement eccpow consensus engine - #10

Open
mmingyeomm wants to merge 3742 commits into
cryptoecc:worldlandfrom
ethereum:master
Open

mmingyeomm wants to merge 3742 commits into
cryptoecc:worldlandfrom
ethereum:master

Conversation

@mmingyeomm

Copy link
Copy Markdown

implements eccpow consensus engine for Worldland Network

jrhea and others added 30 commits June 16, 2026 07:46
`TestTracingHTTPTimeout` still flakes in CI after #35101, failing at the
POST:

    --- FAIL: TestTracingHTTPTimeout (0.26s)
        tracing_test.go:633: request: Post "http://127.0.0.1:43497": EOF

The test sets a short server `WriteTimeout` and posts a blocking call.
`ContextRequestTimeout` leaves a fixed 100ms for the server to write its
timeout response before the HTTP write deadline cuts the connection.

I can't repro it locally, but my theory is that under load that write
can miss the window, so the connection is dropped and the client POST
returns `EOF`, failing the test before it inspects the span. This is the
only test exposed to it because it is the only one that configures a
`WriteTimeout`.

The EOF is benign: the server sets the timeout error on the SERVER span
before attempting the write, independent of whether the client receives
the response. Since that span status is all the test asserts,
`tryPostJSONRPC` tolerates the transport error instead of failing on it.
The stack primitives pop by value: pop() returns the 32-byte value
itself, so every popped operand is copied out of the stack arena before
it is used. The result side was already in place, peek returns a pointer
and binary ops write into the new stack top. This PR fixes the operand
side: pointer-returning primitives (popPtr, popPtrPeek, etc), with the
handlers rewritten to read operands directly from their arena slots.
Every popped operand paid the copy, whatever the op went on to do with
it, so this optimization covers the arithmetic and comparison ops as
much as JUMP, MSTORE, SSTORE and RETURN.

The copy is visible in the assembly. On arm64, master's opLt spends four
instructions moving the popped value through the frame, and the
comparison then reads it back from there:

LDP (R5), (R6, R7) ; load words 0 and 1 of the popped value from the
arena
    LDP  16(R5), (R5, R8)            ; load words 2 and 3
STP (R6, R7), vm.~r0-64(SP) ; store words 0 and 1 into a frame slot
    STP  (R5, R8), vm.~r0-48(SP)     ; store words 2 and 3

With popPtrPeek those four instructions are gone, the frame shrinks from
locals=0x58 to locals=0x18, and the function from 336 to 288 bytes. The
compiler cannot remove the copy itself: uint256.Int is a four-element
array, and Go's SSA does not promote arrays longer than one element to
registers, so a by-value pop pays this round trip no matter how far
inlining gets, for LT exactly as for ADD.

The CALL and CREATE families are deliberately not converted: a child
frame reuses the same stack arena, so parent pointers into popped slots
die when the child pushes. The rule is recorded on the primitives:
pointers stay valid until the next push or any sub call. Converting the
call family safely means materializing scalars before the child call,
left for later work with a call-heavy benchmark to justify it.

### Benchmarks

Measured with the benchmark suite from #35144 (the evm-bench contract
workloads and the block import benchmark), which is not part of this
PR's diff. Apple M4 Max, fixed iteration counts, n=10, all p=0.000. B/op
and allocs/op are statistically identical on every benchmark:

| benchmark | master | PR | vs master |
|---|---|---|---|
| Snailtracer | 60.0 ms | 54.1 ms | -9.8% |
| TenThousandHashes | 13.2 ms | 12.2 ms | -7.8% |
| ERC20Transfer | 11.7 ms | 11.0 ms | -5.5% |
| ERC20Mint | 7.49 ms | 7.02 ms | -6.2% |
| ERC20ApprovalTransfer | 8.92 ms | 8.44 ms | -5.4% |

This PR is independent of #35144 but plays nicely with it: the generated
dispatch there splices these handler bodies, so the in-place forms land
in its fast path too, where they measure larger.

### Testing

The rewritten handlers run on the interpreter's only execution path, so
correctness rests on references outside the change:

- **Consensus fixtures.** The full tests package passes: state tests,
the execution-spec families, blockchain tests.
- **Opcode testcases.** The JSON testcases compare individual opcode
results against committed expected values.
- **Tracer fixtures.** The tracetest reference files pin exact log and
return data shapes, covering the rewritten LOG and RETURN paths.
- **Cross-build differential.** A goevmlab campaign running this
branch's evm against master's evm over generated state tests across four
forks (Prague, Cancun, London, Osaka) with full trace comparison:
160,566 tests, zero divergences.

---------

Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de>
…#35170)

sendInvalidTxs's *eth.TransactionsPacket case iterated `txs` — the
locally-sent invalid transactions, every one of which is in `invalids`
by construction — instead of the transactions actually carried by the
received packet. As a result the loop returned "received bad tx" on the
very first TransactionsPacket the peer sent, regardless of its contents,
and never inspected what was really propagated.

Iterate msg.Items() (the decoded contents of the received packet) so the
"node must not propagate invalid txs" conformance check tests the real
condition instead of producing a false negative.

---------

Co-authored-by: Bosul Mun <bsbs8645@snu.ac.kr>
This PR improves the slot reservation logic in the context of snap/2.

Geth has the mechanism to reserve roughly half the peer slots for peers 
supporting the snap protocol if snap syncing is needed by local node.

With the context of snap/2, this mechanism should be changed that:
we reserve the slot for the "usable snap peer", not blindly for peer
with snap extension enabled (such as legacy snap/1, which can't serve
the snap/2).
)

This PR introduces a new condition that if the local node falls behind
too much and the required BAL for catching up is very likely to be
unavailable, the entire snap sync will be restarting from scratch.

As the defined BAL retention window is weak-subjective-period which is
calculated dynamically. A more conservative threshold is used (90K
blocks) for robustness.

Apart from that, the BAL catchup will be divided into several spans and
apply one by one. It's essential to prevent the potential out-of-memory
panic of placing the entire BAL set in memory.
This PR does two things:

- Expose snap/2 specific sync progress fields
- Seed the sync progress after `loadSyncStatus `
This PR fixes an issue where flat states are continuously persisted
during downloadState, while the sync journal is only persisted at the
end of Sync.

As a result, an unclean shutdown can leave the on-disk flat state ahead
of the journal markers. Some persisted entries may be stale (storage
slots that should have been deleted), and these dangling entries are not
detected or fixed by subsequent state downloads.

To address this, this PR introduces a cleanup step before state
downloading begins. It removes all state entries that are not covered by
the persisted journal markers.
Adds `testing_commitBlockV1`. It is the write companion of `testing_buildBlockV1`:
it builds a block from the provided payload attributes and transactions on
top of the current canonical head, inserts it, and sets it as the new
head, returning the new head hash.

---------

Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de>
Since go 1.18 reflect has `reflect.Pointer` which replaces
`reflect.Ptr`. Newer versions of `govet` will alert. 
See also: https://pkg.go.dev/reflect#pkg-constants
The timer should wait the remaining time, not the elapsed time.
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
```
## 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).
rjl493456442 and others added 30 commits September 8, 2026 09:06
This PR optimizes two things:

- parallelize the chain data write with the state write, the latter one
is slower than the former one
- improve state update encoding with customized rlp encoder
- `TCPPipe` waited on `Accept` after a failed `Dial` without closing the
listener first, so `Accept` never returned and the helper could
deadlock.
- Close the listener on dial failure to unblock `Accept` before draining
the error channel.
- Use Solidity error names for generated ABI lookups and unpacking.
- Keep normalized names for generated Go identifiers.
- Add a regression test for `error bad_thing(uint256 value)`.

## Why

The v2 template used the normalized Go name for `abi.Errors[...]` and
`UnpackIntoInterface`. For underscored or otherwise normalized Solidity
error names, that name is not present in the ABI map, so valid revert
data could not be decoded.
## What

Adds `devp2p discovery listen`, which runs a discovery-only node
speaking **all supported discovery protocol versions (discv4 and discv5)
on a single UDP socket** — the way a real node does via `p2p.Server`.
Until now `devp2p` could only run one protocol per process (`discv4
listen` *or* `discv5 listen`), each on its own socket.

It also exposes the `--rpc` debug API on `discv5 listen`, for parity
with `discv4 listen`.

## Why

`devp2p discv4 listen` / `discv5 listen` is the documented replacement
for the removed `bootnode` tool, but neither can run both protocols on
one port. Other clients and the old bootnode tooling can serve discv4
and discv5 simultaneously on a single UDP port; this closes that gap.

The two protocols are distinguishable on the wire, so they share one
socket: v4 is the primary listener and forwards packets it can't parse
to v5 over an `unhandled` channel, wrapped in a `sharedUDPConn` — the
same mechanism `p2p.Server` already uses.

## Usage

```
# both discv4 and discv5 on one UDP port
devp2p discovery listen --addr [::]:30301

# with the HTTP debug API (discv4_* and discv5_*)
devp2p discovery listen --rpc 127.0.0.1:8080
```

Single-protocol nodes remain available via `devp2p discv4 listen` /
`devp2p discv5 listen`. A future protocol version (e.g. v6) can be added
as an opt-in flag without changing this surface.

## Notes

- `discovery` deliberately has no `--v4`/`--v5` flags: single-protocol
use is already covered by the `discv4`/`discv5` command families, so the
combined command just means "all supported versions."
- v5's RPC API is a subset of v4's (`self`, `lookupRandom`) — `UDPv5`
has no routing-table accessor equivalent to `UDPv4.TableBuckets`, so
there is no `discv5_buckets`.
- Shared-socket shutdown closes v4 before v5: v5's read loop only
unblocks once v4 closes the underlying socket and the `unhandled`
channel.

## Testing

Built and exercised manually:

- `discovery listen` answers both `discv4 ping` and `discv5 ping` on one
port.
- `discovery listen --rpc` serves
`discv4_self`/`discv4_lookupRandom`/`discv4_buckets` and
`discv5_self`/`discv5_lookupRandom`; `discv5_buckets` correctly returns
method-not-found.
- New `discv5 listen --rpc` serves the `discv5_*` API standalone.
- Forcing `ListenAndServe` to fail in combined mode exits cleanly
instead of hanging (shutdown close-order).
- Dual-stack default bind (`[::]`) works.
Adds a `t8n` test fixture for the London fork when the environment does
not provide base fee information.

London/EIP-1559 transitions require either `currentBaseFee` or enough
parent block data to calculate it. This test verifies that `evm t8n`
exits with config error code `3` when both `currentBaseFee` and
`parentBaseFee` are missing.

Tested with:

```sh
env GOCACHE=/private/tmp/go-build-cache GOMODCACHE=/private/tmp/go-mod-cache go test ./cmd/evm

---------

Co-authored-by: lightclient <lightclient@protonmail.com>
This PR reworks the gas hooks a bit, adding a few more types, making the
gas tracing more flat.
The JUMPDEST analysis cache bills entries by value bytes only, so a
budget filled with small bitmaps (17 B per 100-byte contract) silently
holds ~11× its stated size (186–188 B actual per entry vs 17 B billed).

Charge a fixed per-entry overhead (150 B) on insert, refunded on
eviction, mirroring the model already merged for the precompile cache
(#35578).

---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
…_getHeaderByNumber (#35627)

`eth_getHeaderByNumber` now returns `null` for the `pending` tag and for
a `safe` or `finalized` tag that cannot be resolved to a block. Before
this change it returned a pending header with `hash`, `nonce`, and
`miner` nulled, and a `-32000` error for unresolvable tags.

Implements the semantics proposed in ethereum/execution-apis#877 for
these methods (ethereum/execution-apis#874). Block methods are not
changed.
## Root cause

`TestClientCancelWebsocket` wraps the test server with `flakeyListener`,
which starts a connection-kill timer as soon as `Accept` returns. Under
race-detector load, the timer can expire while `Dial` is still
completing the WebSocket handshake, causing setup to panic with
`connection reset by peer` instead of exercising request cancellation.

The 10 ms minimum added in #33002 reduces the probability but does not
remove the ordering race. It recurred in the inherited test in
[0xPolygon/bor
CI](https://github.com/0xPolygon/bor/actions/runs/33586568457/job/100111846852).

## Fix

Signal when initial client setup has completed and make connection fault
timers wait for that signal before starting. Reconnected clients still
receive the same randomized accept delays and connection kills because
the signal remains closed after setup.

## Validation

- `go test -race ./rpc -shuffle=1788322886695128388 -count=1`
- `go test -race ./rpc -run '^TestClientCancel(Websocket|HTTP|IPC)$'
-count=20 -timeout=10m`
- `make all`
- `go run ./build/ci.go test -short`
- `go run ./build/ci.go test`
- `go run ./build/ci.go lint`
- `go run ./build/ci.go check_generate`
- `go run ./build/ci.go check_baddeps`

This only changes test fault-injection timing; runtime RPC behavior is
unaffected.
## Summary
- `getBlock` already sanity-checks uncle and transaction lists against
the header roots.
- Apply the same check for withdrawals so a mismatched `withdrawalsRoot`
and body list is rejected early.

## Test plan
- [x] `go build ./ethclient/...`
- [ ] `go test ./ethclient/...`
This PR adds a few metrics around the chain segment downloading.
A few metrics have been added, exposing the latest progress of snap sync.
### Fixes #23938

### Rationale
When subscribing to contract events via `WatchLogs` / `WatchEvents`,
external nodes (e.g. Polygon/Bor or buggy RPC proxies) may occasionally
deliver logs that do not match the expected topic filter (such as `Sync`
logs instead of `Swap`).

Currently, when `UnpackLog` / `unpack` returns
`ErrEventSignatureMismatch`, the subscription loop terminates and exits
with an error, permanently closing the subscription and causing
downstream consumers to fail.

### Changes
- In `accounts/abi/abigen/source.go.tpl`: ignore
`bind.ErrEventSignatureMismatch` and continue the event loop.
- In `accounts/abi/bind/v2/lib.go`: ignore `ErrEventSignatureMismatch`
in `WatchEvents` and continue the event loop.
- In `accounts/abi/bind/v2/lib_test.go`: added
`TestWatchEventsIgnoreMismatch` to verify that mismatched event logs are
skipped without terminating the subscription.
`eth_simulateV1`, `debug_traceCall` and `eth_createAccessList` panic on
a nil pointer when a call sets `authorizationList` or blob hashes
without `"to"`. `ToTransaction` dereferences `args.To` in the SetCodeTx
and BlobTx branches, and `CallDefaults` never got the guard #35094 added
to `setDefaults`.

`CallDefaults` now rejects it with `ErrSetCodeTxCreate` /
`ErrBlobTxCreate`, leaving `eth_call` and `eth_estimateGas` unchanged.
`setDefaults` is tightened to non-nil too, since `ToTransaction` picks
the SetCodeTx branch for an empty list.
This was found by testing against test_pairing_negative_G2 from py_ecc
https://github.com/ethereum/py_ecc/blob/v8.0.0/tests/core/test_bn128_and_bls12_381.py#L296

This change pulls in the bug fix from
[upstream](cloudflare/bn256@22942e3).

Fixes #35685
Fixes #35671

`eth_simulateV1` with a non-zero `blockOverrides.difficulty` on a
post-merge chain panics (`invalid opcode: PUSH0`).

`makeHeaders` zeroes difficulty for post-merge blocks, but
`BlockOverrides.MakeHeader` then copies the override back onto the
header. `NewEVMBlockContext` leaves `Random` nil when `Difficulty != 0`,
so `Rules` become pre-merge (Shanghai/PUSH0 off) while EIP-2935 still
runs via `chainConfig.IsPrague`. `ProcessParentBlockHash` panics
executing the history contract.

`MakeHeader` now skips the difficulty override on zero-difficulty
(post-merge) headers, matching the documented no-op.

Tests cover `makeHeaders` merge rules and a Prague `SimulateV1` call
with `difficulty: 1`.

---------

Signed-off-by: rome-xi <rome-xi@users.noreply.github.com>
Co-authored-by: rome-xi <rome-xi@users.noreply.github.com>
## Summary
- `runtimeHistogramSnapshot.calc` initialized `max` to `0`, so
histograms whose values are all negative kept `Max() == 0`.
- Seed `max` from the first non-empty bucket, matching how `min` is
already initialized.

## Test plan
- [ ] `go test ./metrics/...`
- [ ] Cover a histogram whose samples are all negative and confirm
`Max()` is the last occupied bucket edge
This is the code needed to produce the rpm builds in the COPR repository
(fedora equivalent to launchpad).

Builds will be found
[here](https://copr.fedorainfracloud.org/coprs/go-ethereum/go-ethereum/)

There is still a need to add a secret in the environment, it will be
added out-of-band.
Adds the four missing Osaka entries to `forkenv.json`, matching the
existing `genesis.json`. The genesis and chain data are unchanged.

This splits the Hive handshake fix out of #35637 so it can be reviewed
separately from the Amsterdam update. Thanks to @ilitteri for
identifying the regression in
#35637 (comment).

Validation on Windows with Go 1.27.0:

- `go test ./cmd/devp2p/... -count=1 -timeout=180s` passes.
- All four added values match the existing genesis settings; no existing
environment values change.
- A local check using Geth's fork-ID calculation reproduces `9736aeb1`
without Osaka and `15e3c946` with it, matching the fixture (next fork:
0).
- `git diff --check` passes.

Full repository build/test/lint/generation checks and an end-to-end
Docker Hive run were not run for this four-entry fix. Earlier full
checks on this Windows setup encountered unrelated lint and
protobuf-generation errors.
The BAL protocol tests currently use a pre-Amsterdam fixture, so their
content-validation path can be skipped. This regenerates the ethtest
data with `hivechain generate --lastfork amsterdam` and updates the
fixture-dependent expectations.

The in-process geth tests now require a BAL for known post-Amsterdam
blocks, which makes both eth/71 and snap/2 exercise the wire hash, RLP
decode, and `BlockAccessList.Validate` paths. External conformance runs
still accept `0x80` for unavailable BALs as required by the specs.

This also adds a guard for BAL commitments across the recent 16-block
test window.

Closes #35632

Tests:
- `go test ./cmd/devp2p/internal/ethtest -count=1`
- `go test ./cmd/devp2p/... -count=1`
…35680)

This PR reworks how body and receipt retrievals are scheduled during
snap sync:

- Cap the request size by considering the 2MB reply limit
- Expire requests blocking the result cache head early and reassign
their items
- Lower the downloader's round trip floor to 500ms
- Increase the result cache to 1GB

What's more, the timeout mechanism has been reworked. A timeout now only
reassigns the request's items while keeping the request alive, instead
of zeroing the peer's capacity and dropping it for small requests. The peer's
capacity is decided by its reply: a late reply is measured on the items that
validated. A peer that never answers is dropped by the existing two minute 
grace period.
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.