Skip to content

eth/consensus : implement eccpow consensus engine - #10

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

eth/consensus : implement eccpow consensus engine#10
mmingyeomm wants to merge 3663 commits into
cryptoecc:worldlandfrom
ethereum:master

Conversation

@mmingyeomm

Copy link
Copy Markdown

implements eccpow consensus engine for Worldland Network

tooshiNoko and others added 30 commits May 22, 2026 11:33
…#35025)

The changes here enable us to fill tests with Amsterdam using geth EVM
bin.

This will be useful for block builder tests using `testing_buildBlockV1`
endpoint and for filling benchmarking compute and stateful tests as
Python is too slow for benchmark tests.

Tested in
[ethereum/execution-specs](https://github.com/ethereum/execution-specs)
with:

```
uv run fill --clean --fork=Amsterdam tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py --evm-bin=$GETH_EVM_PATH
```
Return empty raw bytes when the GraphQL `Block.raw` resolver cannot load
the block body. This matches the nil handling used by the other
block-body-backed resolvers and avoids exposing RLP empty-list bytes as
raw block data.
The first NODES response sets total = min(int(response.RespCount),
totalNodesResponseLimit), With RespCount=0, total=0 but receive become
1; receive == count is never satisfied.
Passing `--state.size-tracking=false` currently cannot disable state
size tracking when it was enabled by the config file because the CLI
path only turns the config value on.

---------

Co-authored-by: Jared Wasinger <j-wasinger@hotmail.com>
Each commit on a PR kicks off a CI run. Those CI jobs run to the finish
regardless, even when new commits have been pushed which make them stale
and useless. This change attempts to cancel any previously running job
for the same PR.
```
● Global JUMPDEST Cache - engine_newPayload benchmark
  ============================================================
  Commit before: a065580 (master)
  Commit after:  faef245 (core/vm: global cache for jumpdest bitmaps)
  Blocks: 1k mainnet (24950066 → 24951065)
  Runs: 3 each, clean ZFS clone per run

                  Before (avg)    With Falcon (avg)   Δ
  Throughput      176.0 MGas/s    190.7 MGas/s        +8.3%
  Mean NP         172.3ms         159.0ms             -7.7%
  p50             162.8ms         150.7ms             -7.4%
  p95             282.4ms         259.8ms             -8.0%
  p99             391.0ms         371.6ms             -5.0%

  Machine: Intel Ultra 7 255H, 62GB DDR5, NVMe (ZFS), governor=performance, turbo=off
  ```

---------

Co-authored-by: Felix Lange <fjl@twurst.com>
…#33880)

Archive nodes store the full history of transactions in the index. This PR
fixes a bug for users who provided the NoPruning field in a YAML config file.
Now geth correctly stores full transaction history if archive is configured via
YAML.

---------

Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
There is currently no way for JSON-RPC clients to discover which
historical data a node can serve without probing with trial-and-error
calls and interpreting opaque error messages (`pruned history
unavailable`).

This makes it hard to build robust tooling on top of nodes that prune
their history, for example nodes started with `--history.chain
postmerge`
or with reduced `TransactionHistory`, `LogHistory`, or `StateHistory`
windows.

This PR implements `eth_capabilities` as defined in
ethereum/execution-apis#755. The method takes no parameters and returns
the current head plus six per-resource capability records:
- `state`
- `tx`
- `logs`
- `receipts`
- `blocks`
- `stateproofs`

Closes #33828
Fixes #35033

## Problem

The GraphQL HTTP handler decoded request bodies directly before
executing the query. Unlike the JSON-RPC HTTP path, `/graphql` did not
have an explicit request body limit before JSON decoding.

A single `Decode` also stops after the first JSON value, so the handler
now requires EOF after the GraphQL request object to ensure oversized
trailing request data is not ignored.

## Changes

- Limit GraphQL request bodies to 5 MiB, matching the existing JSON-RPC
default body limit.
- Return `413 Request Entity Too Large` when the limit is exceeded.
- Require EOF after the request JSON object.
- Add regression coverage for oversized query bodies and oversized
trailing request data.
- Fix an existing GraphQL test fixture that had an unintended trailing
quote after the JSON object.

## Validation

- `gofmt -w graphql/service.go graphql/graphql_test.go`
- `go run golang.org/x/tools/cmd/goimports@latest -w graphql/service.go
graphql/graphql_test.go`
- `go test ./graphql -run TestGraphQLHTTPBodyLimit -count=1`
- `go test ./graphql -count=1`
…atus (#32673)

fixes #32672

This is kind of a band aid solution since it fixes the issue by
bypassing the snap sync expectations of an empty db and attempting to
import the new payload if we're at block 1. The next FCU will set the
status to synced.

Will continue looking to better understand how the above issue arises
and find a more thorough solution.

---------

Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
### Summary

Closes #34621.

`github.com/pion/dtls/v2` is affected by
[CVE-2026-26014](https://nvd.nist.gov/vuln/detail/CVE-2026-26014); the
fix lives in `github.com/pion/dtls/v3`. In this tree, dtls/v2 is pulled
in indirectly via `github.com/pion/stun/v2 v2.0.0` (declared at
`go.mod:53`), which is the only direct consumer — `p2p/nat/stun.go` is
the sole call site.

`github.com/pion/stun/v3` already uses dtls/v3, so bumping `stun`
upgrades the vulnerable dependency without touching `pion/dtls`
directly.

### API check

The v3 surface used by `p2p/nat/stun.go` is byte-identical in shape to
v2:

| Symbol | v2 | v3 |
|---|---|---|
| `Dial` | `func Dial(network, address string) (*Client, error)` | same
|
| `Build` | `func Build(setters ...Setter) (*Message, error)` | same |
| `TransactionID` | `var TransactionID Setter` | same |
| `BindingRequest` | `var BindingRequest = NewType(MethodBinding,
ClassRequest)` | same |
| `Event` | `type Event struct` | same |
| `XORMappedAddress` | `type XORMappedAddress struct { …
GetFrom(*Message) error }` | same |
| `DefaultPort` | `const DefaultPort = 3478` | same |

So the code change is just the import rename plus an alias rename to
keep the local label honest (`stunV2` → `stunV3`).

### Change

`go.mod` / `go.sum`:

- Replace direct `github.com/pion/stun/v2 v2.0.0` with
`github.com/pion/stun/v3 v3.0.1`.
- `go mod tidy` drops every `pion/dtls/v2` and `pion/stun/v2` entry from
`go.sum` and pulls `pion/dtls/v3 v3.0.7`, `pion/stun/v3 v3.0.1`,
`pion/transport/v3 v3.0.8` as the new indirect set.

`p2p/nat/stun.go`:

- Update the import path and rename the alias from `stunV2` to `stunV3`.

### Verification

- `go build ./p2p/nat/` clean.
- `go test ./p2p/nat/ -count=1` passes (26s).
- `grep 'pion/dtls/v2\|pion/stun/v2' go.sum` returns zero matches.

### Notes

- `pion/dtls` is not imported directly anywhere in the tree, so no other
code needs touching.
- `pion/transport/v3` was already in the dependency graph (the `stun/v3`
upgrade just bumps the patch from v3.0.1 → v3.0.8); the v2 transport
drops out cleanly.
…an a year (#35021)

This is another one of my slop-PRs, aimed at reducing the amount of
future slop PRs by doing it all in one go.

All of the deprecated cli flags have been in that state for over a year.
It's time to remove them, especially since they are ineffective.

Note that I kept the code to report and manage deprecated cli flags, as
I assume we will be deprecating more flags in the future.
Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de>
Propagate slog Handle failures when the underlying io.Writer rejects
output.
Add a disableGzip parameter to NewHTTPHandlerStack and httpConfig.
initAuth sets it true so compression is disabled in the engine api.
Public HTTP RPC behavior is unchanged.
Track the transaction only after it was sent out
Updates dtls to newest version
The server already rejects empty batches with -32600. On the client
side, calling BatchCallContext with a zero-length slice on inproc/WS/IPC
transports registers no request IDs but the server still replies with an
error message whose id is null. The dispatch loop has no requestOp to
match it to, so op.resp is never written and op.wait blocks until ctx
deadline.

Short-circuit on len(b) == 0 with the same invalidRequestError the
server uses, so all transports return immediately with -32600.
Because the UBT doesn't differentiate slots from accounts, the content
of the tree can not be exported as a `GenesisAlloc`, which means that
`evm t8n` can not intergrate it. We have tried integrating the new
format into execution-specs, but this is very hard to maintain because
the team doesn't see it as a priority and their own repository is seeing
a lot of churn. This PR adds the ability to capture the structure of
what is being inserted in the tree, so that the information isn't lost
and it can be dumped in the t8n context.

---------

Co-authored-by: felipe <fselmo2@gmail.com>
cuiweixie and others added 30 commits August 5, 2026 14:58
This PR implements the BAL downloader. Once the Amsterdam fork is
enabled, BALs are scheduled for download for BAL-eligible blocks.

Unlike mandatory components such as block bodies, BALs are optional and
are downloaded on a best-effort basis. If a block's essential components
are ready for delivery before its BAL has been retrieved, the block will
be delivered without the BAL.
…st (#35486)

Completes the regular → execution gas rename from #35457. The constant
now matches the EIP-8037 spec name `EXECUTION_PER_AUTH_BASE_COST`.

Pure mechanical rename, no value change.
…35493)

Since #35386 blocks are delivered without waiting for their access list,
a reserved BAL task can outlive its block and hit the stale branch of
`reserveHeaders`, which logs at error level — demote that case to debug.

---------

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Reverts #35403

Partially resolve #35478

Note, it's safe for mainnet, as the block-level accessList hasn't been
enabled yet.
This PR updates some descriptions of snap sync v2, attaching two unit
tests.
This PR introduces the functionalities to persist the local-built bad
blocks alongside additional execution details.
…5501)

`testing_buildBlockV1` decodes `targetGasLimit` from the payload
attributes but does not pass it to `miner.BuildPayloadArgs`. The miner
then falls back to its configured gas ceiling, so the field is silently
ignored. The engine API path (`forkchoiceUpdated`) already passes it
through.

This matters for fixture generation in ethereum/execution-apis, where
`testing_buildBlockV1` builds Amsterdam test blocks and the gas limit
must honor the CL-provided target (see ethereum/execution-apis#857 and
ethereum/execution-apis#862).

The new test builds an Amsterdam block with a target inside the
per-block adjustment bound and checks the payload hits it exactly.
…r cancellation (#35515)

Close the started signal only after the fetchers are registered on
cancelWg, so suspend's Cancel actually waits for them instead of racing
the registration.
…35473)

#35388 keys the cache on `keccak256(address, input)`. Hashing the input
is most of the cost of a lookup, and it scales with input size, so a
large input is expensive to look up even when the result is trivial.
That is why several precompiles had to opt out to stay ahead of it.

@ayamiyaguchi spotted this and wrote the first commit here, which
excluded the precompiles the key cost was hurting most. This takes the
same finding in a different direction by making the key cheap in the
first place, so those precompiles do not need excluding.

The solution here is to key on the input bytes directly, plus three
changes that follow from it:

1) Entries used to share one LRU, so a high-volume precompile could
evict the pairing and modexp results the cache exists to hold. Each
precompile now gets its own.

2) Now that the key is the input, entries run from tens of bytes to
kilobytes, and a count means very different memory depending on the mix.
Each precompile gets 1 MiB of keys and values.

3) A precompile is cached only if it says so, and can narrow an input to
the bytes that determine the result via `NormalizeInput` so padding
lands on the entry the unpadded call already made.

### Benchmarks

Medians of five runs. 

#### Lookup versus running the precompile, at real vector sizes

| precompile           |  input |     #35388 |    this PR |       run |
|----------------------|--------|------------|------------|-----------|
| ECREC                |    128 |     480 ns |      55 ns |   18.2 µs |
| SHA256               |    128 | not cached |      58 ns |     79 ns |
| RIPEMD160            |    128 | not cached |      55 ns |    454 ns |
| ID                   |    128 | not cached | not cached |     16 ns |
| MODEXP               |    609 |     1.1 µs |     128 ns |    2.9 µs |
| BN254_ADD            |    128 |     478 ns |      54 ns |    1.0 µs |
| BN254_MUL            |     96 |     279 ns |      52 ns |   13.4 µs |
| BN254_PAIRING        |    384 |     698 ns |      85 ns |  490.1 µs |
| BLAKE2F              |    213 |     486 ns |      67 ns |    118 ns |
| KZG_POINT_EVALUATION |    192 |     488 ns |      61 ns |  785.8 µs |
| BLS12_G1ADD          |    256 |     697 ns |      68 ns |    1.9 µs |
| BLS12_G1MSM          |    160 |     488 ns |      60 ns |   95.4 µs |
| BLS12_G2ADD          |    512 |     911 ns |     103 ns |    2.9 µs |
| BLS12_G2MSM          |    288 |     708 ns |      74 ns |  181.3 µs |
| BLS12_PAIRING_CHECK  |    384 |     713 ns |      85 ns |  445.6 µs |
| BLS12_MAP_FP_TO_G1   |     64 |     282 ns |      45 ns |   30.7 µs |
| BLS12_MAP_FP2_TO_G2  |    128 |     490 ns |      55 ns |  135.0 µs |
| P256VERIFY           |    160 |     494 ns |      60 ns |   33.6 µs |

RIPEMD160 wasn't cached before and a lookup now costs 55 ns against 454
ns to run it. BN254_ADD was cached previously, but at 478 ns to look up
against a 1 µs run the cache was barely paying for itself. With this
change, the lookup is now 54 ns and much more worth it.

#### The same measurement at the largest eligible input, 8 KiB

| precompile           |     #35388 |          this PR |       run |
|----------------------|------------|------------------|-----------|
| ECREC                |    12.9 µs |            74 ns |    131 ns |
| SHA256               | not cached |           1.1 µs |    2.6 µs |
| RIPEMD160            | not cached |           1.2 µs |   17.9 µs |
| ID                   | not cached |       not cached |    969 ns |
| MODEXP               |    13.0 µs |            56 ns |     50 ns |
| BN254_ADD            |    12.9 µs |            67 ns |     60 ns |
| BN254_MUL            |    12.9 µs |            56 ns |    6.4 µs |
| BN254_PAIRING        |    12.8 µs | 5 ns, not cached |      2 ns |
| BLAKE2F              |    12.9 µs | 5 ns, not cached |      1 ns |
| KZG_POINT_EVALUATION |    12.9 µs | 4 ns, not cached |      1 ns |
| BLS12_G1ADD          |    12.8 µs | 5 ns, not cached |      1 ns |
| BLS12_G1MSM          |    13.0 µs | 4 ns, not cached |      1 ns |
| BLS12_G2ADD          |    13.0 µs | 4 ns, not cached |      1 ns |
| BLS12_G2MSM          |    12.9 µs | 4 ns, not cached |      1 ns |
| BLS12_PAIRING_CHECK  |    13.0 µs | 5 ns, not cached |      1 ns |
| BLS12_MAP_FP_TO_G1   |    13.0 µs | 4 ns, not cached |      1 ns |
| BLS12_MAP_FP2_TO_G2  |    12.8 µs | 4 ns, not cached |      1 ns |
| P256VERIFY           |    13.0 µs | 4 ns, not cached |      1 ns |

The `#35388` column is flat at ~13 µs because the key is a hash of the
input and does not depend on which precompile receives it. In the `this
PR` column, the number beside "not cached" is the cost of deciding not
to build a key: those precompiles require an exact length, so an 8 KiB
input is one they will reject, and there is no result worth keying. The
`run` column here is mostly a length rejection rather than work, so it
is context for the other two columns rather than a comparison.

---------

Co-authored-by: aya <aya@ethereum.org>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
StateSize is a development tool for calculating and tracking the size of
the state. It was requested by ethPandaOps a while ago, but it has since
been superseded by another approach that captures state changes via a
live tracer. Therefore, this tool can be retired to reduce maintenance
overhead.
…ync target (#35433)

Fixes #35418.

After a restart, the syncer sets the finalized marker to head−64 and the
safe marker to head−32 on every downloader sync event, ignoring epoch
boundaries. Since this service is registered unconditionally and
`api_backend` serves `CurrentFinalBlock()` verbatim,
`eth_getBlockByNumber("finalized")` can return a mid-epoch block that
was never finalized and can still be reorged.

The synthesized markers exist to make `finalized`/`safe` usable when no
consensus client is attached. This change scopes them to exactly that
case: they are only set when an explicit sync target has been specified
(`--synctarget`), which is the only mode where no CL supplies real
checkpoints. Normal nodes now never override consensus-client
checkpoints.

`TestSyncerDoesNotInventFinalityMarkers` syncs a node to head with no CL
finality input and asserts the chain's finalized/safe markers stay
unset; it fails on master (finalized invented at head−64) and passes
with this change.

---------

Co-authored-by: SillyZir <269283839+SillyZir@users.noreply.github.com>
Co-authored-by: Jonny Rhea <5555162+jrhea@users.noreply.github.com>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
This PR explicitly clears the referenced block access list at the end of
each transaction. This is essential because accounts are shadow-copied
into the global block access list, and it prevents accidental mutations
through stale references in StateDB.
`BlobPool.Init` builds the lookup, index and store without holding
`p.lock`, and `eth/backend.go` publishes the pool to `blobpool.NewCache`
before `txpool.New` runs Init. Cache.update spawns a goroutine calling
`getByVhash`, so it can read the pool mid-construction:

```
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x28]
    blobpool.(*BlobPool).getByVhash(...)  blobpool.go:1303
    blobpool.(*Cache).update.func1()      cache.go:429
```

`Init` fills the lookup inside `billy.Open`, whose index callback runs
`parseTransaction` -> `trackTransaction`, and assigns `p.store` only
once `billy.Open` returns. For that window a lookup hit names a
transaction whose store does not exist yet, and `p.store.Get`
dereferences nil.

Build the cache after `txpool.New` so no reader exists while `Init` runs
-- `getByVhash` has exactly one caller -- and have `getByVhash` read the
store under the same lock as the lookup, returning nil when it is not
set.

A benchmark harness that restarts the client once per test hit this on
1-4% of starts; a node that starts once rarely will.
…ocol version (#35524)

eth/72 announces blob transactions without the blob payload while eth/71
includes it, so the same transaction is announced with different
sizes. Compare each announcement against the size expected for that
peer's version instead of a single size so that honest peers on either version
are no longer dropped on delivery.
…get (#35526)

#35473 keys the precompile cache on the input, but SizeConstrainedCache
only counts the value’s bytes, so a cacheable empty output (e.g. a
failed ECRECOVER) is never evicted and grows the cache without bound.

Skipping empty outputs alone would still leave sha256/ripemd160 ~256x
over budget, and would only hold as long as every failing output happens
to be empty.
…on (#35528)

When the full data domain (cell indices 0..DataPerBlob-1) is present, a
blob is the concatenation of its data cells, so it can be reconstructed
without any KZG work. Add BlobsFromDataCells, which returns the blobs by
concatenation when the data cells are present in canonical order and
declines otherwise (so callers fall back to RecoverBlobs). Its accepted
inputs are a strict subset of those accepted by RecoverBlobs, so a
successful result is byte-identical; being pure byte copying it is
independent of the selected KZG backend.

Shared primitive: used both to skip KZG recovery when serving blobs and
by the cell-recovery path (RecoverCells).
A few updates for glamsterdam devnet, taking the original commits from
@spencer-tb

- making the TargetGasLimit as the optional parameters
- ensuring the system call's code exists (EIP-7002/7251/8282)
- rework the fork selection rules in the engine API

---------

Co-authored-by: spencer-tb <spencer.tb@ethereum.org>
Add RecoverCells, which returns all CellsPerBlob cells per blob from a
sufficient subset.

RecoverBlobs only exposes recovered blobs; serving or persisting the
extension cells of a sparse-blobpool transaction needs the full 128-cell
set. Add RecoverCells, which returns all CellsPerBlob cells per blob
from a sufficient subset.

When the full data domain (cell indices 0..DataPerBlob-1) is present
(the common case for pooled transactions) the blobs are a free
concatenation of the data cells and every cell follows from a systematic
extension via ComputeCells (~2-6ms/blob), skipping the KZG erasure
solve. Otherwise it falls back to the erasure recovery path
(~15-20ms/blob), which now surfaces the library's full extended cell set
instead of discarding it down to blobs as RecoverBlobs does. Both paths
return byte-identical cells in canonical order.

Cells only; cell proofs are never recomputed (callers retain the proofs
shipped with the transaction). Tested on both the gokzg and ckzg
backends, fast and slow paths, against the original cells.

Note: the same fast-path optimization could also be pushed down to gokzg
and ckzg. There are both arguments for (the primitive becomes faster in
some cases, same for the rest of cases) and against (it is not the role
of the crypto lib to be intelligent here), so I went with the wrapper
for now.
…35542)

The test set the local UDP port via ln.Set(enr.UDP(...)), but the "udp"
ENR entry is owned by the endpoint predictor: as soon as the first node
received a PONG, updateEndpoints recomputed the endpoint with no
fallback port set and deleted the entry. Later nodes bootstrapping from
that node's record then failed with "bad bootstrap node: missing UDP
port".

Use SetFallbackUDP like startLocalhostV4 already does, so the port
survives endpoint statements.

fixes CI errors like in
https://github.com/ethereum/go-ethereum/actions/runs/31859911877/job/94953524792?pr=35529
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.