This is the implementation of EIP-8070 Sparse Blobpool. It introduces
protocol version eth/72 which relays blob transaction cells instead of
full blobs.
The blobpool now store 'incomplete' transactions, where only some of
the cells are provided. The stored cell indexes are taken from the
custody bitmap, which is provided by the consensus layer in
forkchoiceUpdatedV4. This method will be called once Glamsterdam
activates, and the default custody is full custody, so for now there
is no change in the amount of stored cells for now.
The main entities added are the BlobBuffer and BlobFetcher, which work
together to track and fetch missing cells from connected peers. The
partial transactions become available for inclusion in blocks when
they are covered by enough peers that hold all cells.
This change also introduces engine_getBlobsV4, which allows for
cell-based responses (and partial blobs with only some of the cells).
We maintain backward compatibility with getBlobsV3 which expects full
blob responses by recovering the blob from available cells. Since this
process is resource-intensive, we proactively cache the conversion so
it is ready in time for getBlobsV3 calls. This mechanism will be
removed once support for getBlobsV4 is universal across all consensus
layer implementations.
devp2p tests for eth/72 are not part of this initial change. This is
to avoid breaking test success status for execution clients that do
not have eth/72 implemented yet. The tests will be added in a
subsequent change.
---------
Co-authored-by: Felix Lange <fjl@twurst.com>
- Move `msg.Discard` defer ahead of the max message size check in
`handleMessage`.
- Ensures oversized messages are released when the handler returns
early.
The DNS discovery crawler (ethereum/discv4-crawl) builds signed enrtree
lists by crawling the network and running the collected records through
`devp2p nodeset filter` and `devp2p dns sign`. Those records come from
external nodes, and `enr.Record` keeps entries it can't decode as raw
RLP, so a self-signed record with an out-of-range port (EIP-778 defines
ports only as "big endian integer", not `uint16`) can round-trip
verbatim into a signed tree. Consumers that decode ports strictly then
fail to decode that record.
Two publish-side checks:
- `MakeTree` rejects a record if a present port entry
(`tcp`/`tcp6`/`udp`/`udp6`/`quic`/`quic6`) does not decode as a
`uint16`. This is an invariant at the signing boundary: geth won't sign
a tree containing a record with an undecodable port, regardless of how
the node list was produced. Absent and zero ports are unaffected.
- `devp2p nodeset filter -dialable` keeps only nodes advertising a
usable RLPx port (non-zero `tcp`/`tcp6`/`quic`/`quic6`), letting the
crawler drop discovery-only and unreachable nodes so consumers aren't
handed peers they can't connect to.
The two are deliberately separate: the `MakeTree` check is a correctness
guard that always applies, while `-dialable` is an opt-in selection
filter for the crawler pipeline. A follow-up will add `-dialable` to
discv4-crawl's `filter_list`.
When we are deploying library dependencies, if the `TransactOpts` nonce
is unset we will choose the nonce of the next deployment transaction
based on the pending nonce of the sender. If a previous library
deployment transaction was made but not yet accepted into the pool, the
pending nonce will not be updated for the the next deployment
transaction.
This PR introduces a new method to the bind API `WaitAccepted` which
poll until a submitted transaction hash is accepted into the pool or
rejected. The bindings for v1 are updated to invoke this method after
deploying each library dependency.
## Summary
- Only apply user-configured `MaxBlobsPerBlock` when it is strictly
below the protocol-defined maximum.
- Prevents the miner from building blocks that exceed the consensus blob
limit.
## Test plan
- [x] `go test -short ./miner/`
WithAttrs and terminalFormat appended to h.attrs directly, which can
mutate the shared slice when it has spare capacity. Clone attrs first to
avoid corrupting parent handler state.
The peer dropper periodically disconnects random peers to create churn.
This was previously blind to peer quality.
This PR adds peer-score based peer protection, handling the
multi-dimensionality problem of peer scoring through the concept of
protected peer pools.
---------
Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
Co-authored-by: healthykim <bsbs8645@snu.ac.kr>
## Summary
Sanity fixes surfaced by running the EELS `tests@v20.0.0` fixture
release (63,109 blockchain tests) through `evm blocktest`.
Also bumps CI to consume the new release: `build/checksums.txt` now
points at `tests@v20.0.0` / `fixtures.tar.gz` from
`ethereum/execution-specs` (supersedes the archived EEST repo's
`fixtures_develop`).
---------
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
This PR does a few things:
- reject `debug_setHead` if the target is even before the pivot block
(if non-nil)
- reject `debug_setHead` if in path mode, the target is not recoverable
- decouple the chain rewinding and state recovery in path mode and
recover the state in one shot
---------
Co-authored-by: jonny rhea <5555162+jrhea@users.noreply.github.com>
Closes#35314.
### Problem
`TransactionArgs.ToTransaction` selects `SetCodeTxType` when an
`authorizationList` is present, but then unconditionally downgrades to
`LegacyTxType` when `gasPrice` is set:
```go
case args.AuthorizationList != nil || defaultType == types.SetCodeTxType:
usedType = types.SetCodeTxType
...
if args.GasPrice != nil {
usedType = types.LegacyTxType
}
```
A legacy transaction cannot carry an EIP-7702 authorization list, so the
list is silently dropped. `eth_sendTransaction`, `eth_signTransaction`
and `eth_fillTransaction` can then return a plain legacy
transaction/hash even though the requested delegation update or
revocation was never included.
The downgrade also masks a latent issue: `setFeeDefaults` returns early
once `gasPrice` is set (without `authorizationList`) and never fills
`MaxFeePerGas`/`MaxPriorityFeePerGas`. Building the `SetCodeTx` without
the downgrade would hit
`uint256.MustFromBig((*big.Int)(args.MaxFeePerGas))` with a nil fee cap
and panic. Erroring early is therefore the correct behavior.
### Fix
Reject the `gasPrice` + `authorizationList` combination in
`setFeeDefaults`, mirroring the existing `gasPrice` / EIP-1559 guard, so
the request fails explicitly instead of producing a transaction that
omits the authorization list.
### Test
Added a `setFeeDefaults` case asserting the new error. Verified
fail-on-main: with the guard reverted the test fails (`expected error:
both gasPrice and authorizationList specified`); with the guard it
passes. Full `internal/ethapi` package, `go vet` and `gofmt` are clean.
### Note
The same silent-drop applies to `gasPrice` + `blobVersionedHashes` (blob
transactions also cannot be legacy). I scoped this PR to the reported
`authorizationList` case; happy to extend the guard to blob hashes in
the same spot if preferred.
This is an edge case found by @weiihann.
Under 8038, the cold storage access cost is increased to 3,000 gas,
which exceeds the sentry check threshold. Therefore, the sentry check no
longer guarantees that the remaining gas is sufficient to cover a cold
slot access.
Therefore, an additional access affordability check is added to
eliminate the potential DoS vector.
This PR clears `journal.writer` immediately after `Close()` in `rotate` and `setupWriter`,
before checking the error. This prevents leaving a stale file handle that could be reused
if close fails.
---------
Co-authored-by: Bosul Mun <bsbs8645@snu.ac.kr>
Passing `--fuzz=false` currently still selects blocktest fuzz output
mode because the command checks whether the flag was set.
This switches the blocktest fuzz-mode checks to use the boolean flag
value, so explicit false keeps the normal output path while `--fuzz`
still enables fuzz-oriented reporting.
The HTTP JSON-RPC server caps request bodies at a hardcoded 5 MB
(`defaultBodyLimit`), with no way to raise it. EEST bloatnet depth
benchmarks post worst-case batch requests larger than that during
fill-stateful, which the server rejects with `413 Request Entity Too
Large`.
This adds `node.Config.HTTPBodyLimit` (default 5 MB), wired through to
the HTTP/WS server config, and exposes it via `--rpc.http-body-limit`
(value in **megabytes**, default 5). Default behaviour is unchanged.
## Summary
- Add the missing `forks.Amsterdam` case to `ChainConfig.Timestamp`.
- Callers can now look up the Amsterdam fork activation time.
## Test plan
- [x] `go test -short ./params/`
This PR fixes five remaining differences between master and
glamsterdam-devnet-6:
- RegularCost for Auths has been increased, since 8037 increases the
WARM_ACCESS cost
- Floor is anchored to the transaction base cost, not the intrinsic cost
- Auth destinations need to be recorded in the BAL before the call is
executed
- Change the place where intrinsic gas is verified in calls to delegated
addresses
- Refund state gas directly to reservoir in outer tx frame
---------
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
`FairMix.AddSource` takes ownership of the supplied iterator, but if the
mixer has already been closed it currently returns without closing that
iterator. Close the rejected source in this shutdown path so callers
racing with `Close` do not leak iterator resources.
The drop helper uses sort.Search on the sorted wallet list, but the
returned index can point at the next greater wallet when the target URL
is missing. Fix this by rewriting the drop to use slices.DeleteFunc and a map.
---------
Co-authored-by: Felix Lange <fjl@twurst.com>
Increment `dropCount` on every TALKREQ dropped due to overload timeout.
Previously the counter was only updated when the throttled warning log
was emitted.
This PR addresses an issue in the eth71 `BlockAccessListsMsg` handler,
specifically:
- if the requested bal is not accessible in the server side, 0x80
(EmptyString) will be returned as the marker
- at the client side, old message definition
`rlp.RawList[RawBlockAccessList]` assumes all the elements are List
- the message with 0x80 (kind = string) won't be decoded correctly
- the peer will be disconnected
The message definition has been changed to `rlp.RawList[rlp.RawValue]`,
which is aligned with the one in SNAP/2 protocol.
EIP-7928 requires that each address appears exactly once in the block
access list.
In the `BlockAccessList.Validate`, the strict `isStrictlySortedFunc` is
required to detect the duplicated accounts.
The LookupRandom RPC handler obtains a node iterator from
RandomNodes() but never closes it.
RandomNodes() returns a lookupIterator backed by a cancelable
context derived from the listener's lifetime context
(newLookupIterator -> context.WithCancel). The iterator's
Close() is what calls the cancel func, so each LookupRandom call
that never closes leaks the cancel func (and any in-flight lookup
goroutine) until the discv4 listener shuts down. When the listener
serves the RPC API (discv4 --rpc) it is long-lived, so repeated
LookupRandom calls accumulate the leak.
Close the iterator when the handler returns. This matches how the
crawler already releases the same RandomNodes() iterators
(crawl.go closes every iterator it consumes).
SignTx populated BlobHashes and the sidecar fields (Blobs/Commitments/
Proofs) for a blob transaction but never set args.BlobFeeCap. As a
result the external (clef) signer received maxFeePerBlobGas:null and
signed a transaction inconsistent with the one passed in, silently
dropping the blob fee cap.
Set args.BlobFeeCap from tx.BlobGasFeeCap() so the signing request
faithfully reflects the input transaction. This mirrors the existing
handling of the other blob-tx fields.