Commit graph

3154 commits

Author SHA1 Message Date
CPerezz
fcc0587ec3
core/state,triedb/pathdb: fix bintrieFlatReader disk-layer shape via per-offset extraction
Addresses review finding C2 (+ I5, S5, T2, T3, T12).

Before this commit, bintrieFlatCodec.ReadAccount returned the FULL
variable-length stem blob from disk while the in-memory diff-layer
buffer stored per-offset 32-byte values. The consumer,
bintrieFlatReader.Account, enforced len(basicBlob)!=32 → error, so
every disk-layer hit produced "bintrie BasicData leaf invalid length"
in production the moment the write buffer flushed. TestBintrieFlatReaderEndToEnd
did not catch this because it never forced a buffer → disk flush.

Fix: make bintrieFlatCodec.ReadAccount extract the offset from the
stem blob (mirroring ReadStorage), so the disk path and the buffer
path return the same 32-byte per-offset shape. Update
AccountCacheKey/StorageCacheKey to embed the full 32-byte key
(prefix + 31-byte stem + 1-byte offset), since caching under a
stem-only key would collapse BasicData and CodeHash into the same
slot and return the wrong value on the second hit. Update
Flush's cache-update loop to store per-offset entries from the
aggregated write set.

Design note: I considered the alternative of introducing a new
StemBlob(stem) interface method that returns the full blob synthesized
from a stem-level lookup index. Rejected because (a) the index is a
new data structure with its own consistency invariants, (b) the
per-offset approach is strictly local to the codec + reader, and (c)
the "1 Pebble read per Account" locality benefit is preserved at the
OS page cache level — both offsets at the same stem live in the same
Pebble block, so the second read is effectively free.

bintrieFlatReader.Account still does two AccountRLP lookups; the
torn-read hazard is gated by a new load-bearing invariant test,
TestBinaryHasherWritesBothBasicAndCodeHash, which asserts that
binaryHasher.updateAccount always emits both BasicData and CodeHash
leaves together. A future code-only update that broke this invariant
would fail the test.

Tests added:
  * TestBintrieFlatReaderEndToEndAfterFlush — explicitly flushes via
    tdb.Commit(root, false) and re-reads through a fresh StateReader.
    This is the smoking-gun regression for C2.
  * TestBintrieFlatReaderMultipleOffsetsPerStem — multiple offsets at
    the same stem (BasicData, CodeHash, header storage slots) all
    round-trip post-flush.
  * TestBintrieCodecCrossFlushRMW — two Flush calls to the same stem
    from different "blocks" correctly merge on disk, with prior
    offsets preserved.
  * TestBinaryHasherWritesBothBasicAndCodeHash — locks down the hasher
    co-write invariant that bintrieFlatReader.Account relies on.

Existing tests updated to match the new per-offset ReadAccount
semantics:
  * TestBintrieCodecAccountRoundTrip, TestBintrieCodecMultipleWritesSameStem,
    TestBintrieCodecDeleteAccount — now read per-offset rather than
    calling extractStemOffset on the raw blob.
  * TestBintrieCodecCacheKeysDisjoint — additionally verifies two
    offsets at the same stem produce distinct cache keys.

Error messages in bintrieFlatReader now include address and length
context (S5).
2026-04-15 15:00:40 +02:00
CPerezz
bfb77d98f6
core/state,triedb/pathdb: enable bintrie flat state reads end-to-end
Wires the pieces from Commits 1-9 into a running system:

* triedb/pathdb.New: install the bintrieFlatCodec when isVerkle is set,
  backed by the same verkle-namespaced db used for trie nodes.
* triedb/pathdb.database.go: drop isVerkle from the noBuild guard so the
  bintrie generator (Commit 9) runs on startup, and remove it from the
  generateSnapshot call path for the same reason.
* triedb/pathdb.disklayer.revert: hard-fail on bintrie because the
  reorg path would replay merkle-shaped origin records against a
  per-stem layout. Tracked in BINTRIE_FLAT_STATE_REORG_GAP.md.
* triedb/pathdb.journal: add IsBintrie to journalGenerator (rlp:"optional"
  so v3 journals still decode) and make journalProgress a method on
  generator so it stamps the active scheme; loadGenerator discards any
  journal whose scheme does not match the database, forcing a fresh
  regeneration.
* triedb/pathdb.reader: export RawStateReader, a small extension of
  database.StateReader that exposes AccountRLP so callers outside the
  package can reach the raw flat-state bytes without going through the
  slim-RLP decode path that assumes merkle shape.
* core/state.reader: add bintrieFlatReader, the bintrie equivalent of
  flatReader. It derives the EIP-7864 stem keys from (addr, slot),
  performs two AccountRLP lookups per Account call (BasicData +
  CodeHash), and decodes via bintrie.UnpackBasicData. Storage reads go
  through a single AccountRLP lookup at the slot's full bintrie key.
* core/state.database.StateReader: dispatch to bintrieFlatReader when
  the path database is in verkle mode; merkle path unchanged.

Depends on the lookup sentinel fix in the previous commit; without it
missing-account reads on bintrie misreport as "layer stale".
2026-04-15 15:00:40 +02:00
CPerezz
a1ff36d9e1
core/state,triedb/pathdb: wire bintrie leaves through stateUpdate
Drains the binaryHasher's LeafProducer side-channel in StateDB.commit and
threads the stem writes through stateUpdate.encodeBinary into the pathdb
state set as per-offset accountData entries (key = stem||offset, value =
32-byte leaf or nil for clears).

The flat-state codec gains a Flush method that owns the in-memory→disk
write path, replacing the codec-agnostic per-entry loop in writeStates.
The merkle codec preserves its historical per-entry behavior verbatim;
the bintrie codec aggregates per-offset writes by stem so each stem hits
disk via a single read-modify-write, satisfying the codec's pre-aggregation
requirement and updating the clean cache with the merged blob it just
produced (no extra disk read).

stateUpdate.encodeBinary returns empty origin maps for the bintrie path:
state-history rollback for bintrie is deferred to a follow-up PR (see
BINTRIE_FLAT_STATE_REORG_GAP.md), and the diskLayer.revert path will
panic before consuming origins anyway.
2026-04-15 15:00:40 +02:00
CPerezz
29ef7576d9
core/state: hook leaf production in binaryHasher
binaryHasher now implements the new LeafProducer optional extension to
the Hasher interface. Every UpdateAccount, UpdateStorage, and delete
path records the corresponding (stem, offset, value) write into an
internal buffer, which the caller drains once per block via
DrainStemWrites() and hands to the pathdb flat-state layer through the
stateUpdate (wired up in the next commit).

Three kinds of writes are recorded:

  - Account create/update: two writes (BasicData at offset 0,
    CodeHash at offset 1), sharing the same 31-byte stem. BasicData
    is produced via bintrie.PackBasicData so the flat-state blob
    is bit-identical to what the trie layer packs internally.

  - Storage update: one write per slot. Non-zero values become
    right-justified 32-byte blobs; the zero value (the bintrie's
    "delete" convention) becomes 32 zero bytes, matching the trie's
    tombstone-with-zero semantics so the flat-state mirror stays
    bit-identical to the StemNode.Values entry.

  - Account delete: two clear writes (nil Value) for offsets 0 and 1.
    Storage slots and code chunks at the same or other stems are NOT
    touched; pre-EIP-6780 full-wipe is a documented scope limitation.

The LeafProducer interface lives on Hasher and is strictly opt-in —
merkleHasher does not implement it, and callers detect capability via
a type assertion. This keeps the read-side/write-side split of the
existing Hasher cleanly extended: hashers that have a concept of
flat-state leaves can expose them; hashers that don't (MPT) are
unaffected.

Tests cover:

  - TestBinaryHasherLeafProduction: account update produces 2 writes
    at offsets 0+1 with matching stem; drain is destructive; storage
    update emits one matching write; zero-value storage writes 32 zero
    bytes; delete emits 2 clear writes.
  - TestMerkleHasherNoLeafProducer: merkleHasher does NOT satisfy the
    LeafProducer interface (the capability is opt-in per hasher).

The collected stem writes are not yet propagated anywhere — a later
commit wires DrainStemWrites into StateDB.IntermediateRoot so the
writes flow through stateUpdate and the pathdb stateSet into the
flat-state layer.
2026-04-15 15:00:40 +02:00
CPerezz
a2f00cb291
core/rawdb: add BinTrieStemPrefix and stem accessors
Reserve a new top-level key-value namespace for bintrie flat-state
entries: BinTrieStemPrefix = "X" (chosen to be free at the top level so
unwrapped-db callers do not collide with blockBodyPrefix "b"). In
practice pathdb nests this namespace under VerklePrefix "v" via
rawdb.NewTable, so the on-disk key is effectively "v"+"X"+stem.

A stem is the 31-byte common prefix of the 32-byte tree key defined in
EIP-7864. The stored value is a packed blob containing the populated
(offset, value) pairs at that stem; BasicData (offset 0), CodeHash
(offset 1), header storage (offsets 64-127), code chunks (offsets
128-255) and main-storage slots can all be extracted from the same
blob by a single Pebble read, matching the on-trie StemNode grouping.

Add Read/Write/DeleteBinTrieStem alongside the existing snapshot
accessors, and a private binTrieStemKey helper in schema.go. No
callers yet — the bintrieFlatCodec in the next commit consumes them.
Matches the same style as ReadAccountSnapshot et al.; the codec and
integration tests downstream will exercise them.
2026-04-15 15:00:40 +02:00
CPerezz
64d185616c
core/state: plumb CodeSize through AccountMut for binaryHasher
binaryHasher.updateAccount computed codeLen from len(account.Code.Code),
which is only non-zero when the code itself was modified in the current
block. For balance- or nonce-only updates account.Code is nil and the
computed codeLen was 0, silently overwriting the code_size field packed
into the bintrie BasicData leaf (EIP-7864 bytes 5-7) with zero every
time a contract was touched without a code write.

The TODO(rjl493456442) on updateAccount acknowledged this. Fix it by
adding a CodeSize field to AccountMut and having the caller at
StateDB.IntermediateRoot populate it via stateObject.CodeSize(), which
returns len(obj.code) when the bytes are loaded, otherwise falls back
to a code-size lookup via the reader. The binary hasher then passes
account.CodeSize straight to BinaryTrie.UpdateAccount as its codeLen
argument, and the TODO is removed.

Rationale for placing CodeSize on AccountMut rather than Account:
AccountMut already carries Code *CodeMut — the new bytecode, which is
not a field of Account — because code is write-time data that is not
persisted in the flat-state format (SlimAccountRLP). CodeSize has the
identical lifecycle: it is not in SlimAccountRLP, it is not populated
by any reader, and it is only consumed by the hasher at write time.
Mirroring Code's placement keeps the read-side/write-side split honest
(Account models the persisted flat-state record; AccountMut adds the
code-related write-time parameters). If the bintrie flat-state format
is later extended to carry code_size, CodeSize can be promoted onto
Account at that time.

merkleHasher is unaffected: StateTrie.UpdateAccount ignores its codeLen
parameter, so the wrapTrie.UpdateAccount shim continues to pass 0 and
no state-root divergence is introduced on the MPT path.

Regression test TestVerkleCodeSizePreserved verifies that the state
root produced by "create contract, commit, reload, modify balance,
commit" matches the root of a single-step construction of the same
final state. Before the fix the roots diverge:

  path A (reload + balance): 1a675599...
  path B (fresh, same state): de0cfb03...
2026-04-15 15:00:39 +02:00
Gary Rong
533d2109d5
core: fix memory leaking 2026-04-15 15:00:39 +02:00
Gary Rong
aec9c18432
core/state: improve binary hasher 2026-04-15 15:00:39 +02:00
Gary Rong
a2496465f9
core: fix cross validation 2026-04-15 15:00:39 +02:00
Gary Rong
d57dca07b1
core/state: integrate witness collector 2026-04-15 15:00:39 +02:00
Gary Rong
5e23a29b73
core/state: integrate prefetching into merkle hasher 2026-04-15 15:00:38 +02:00
Gary Rong
91298c8655
core/state: implement binary hasher just for demonstration 2026-04-15 15:00:38 +02:00
Gary Rong
282cece030
core/state: implement merkle hasher 2026-04-15 15:00:38 +02:00
Gary Rong
38c7021c73
core/state: invoke prefetcher 2026-04-15 15:00:38 +02:00
Gary Rong
1ae462f08d
core/state: build hasher skeleton 2026-04-15 15:00:38 +02:00
Gary Rong
9daaef1923
core/state: remove trie prefetcher and witness from stateDB 2026-04-15 14:59:05 +02:00
Gary Rong
e2c00d6c96
core/state: add hasher interface definition 2026-04-15 14:59:05 +02:00
Gary Rong
00c3b6da6c
core/state: rework trie prefetcher 2026-04-15 14:58:57 +02:00
rjl493456442
ef0f1f96f9
core/state: ignore the root returned in Commit function for simplicity (#34723)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
StateDB.Commit first commits all storage changes into the storage trie,
then updates the account metadata with the new storage root into the 
account trie.

Within StateDB.Commit, the new storage trie root has already been
computed and applied as the storage root. This PR explicitly skips the 
redundant storage trie root assignment for readability.
2026-04-15 11:15:43 +08:00
cui
2253fce48d
core/types: remove redundant ')' (#34719)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
2026-04-14 22:09:17 +08:00
rjl493456442
eb67d61933
cmd/geth, core/state, tests: rework EIP7610 check (#34718)
This PR simplifies the implementation of EIP-7610 by eliminating the
need to check storage emptiness during contract deployment.

EIP-7610 specifies that contract creation must be rejected if the
destination account has a non-zero nonce, non-empty runtime code, or 
**non-empty storage**.

After EIP-161, all newly deployed contracts are initialized with a nonce
of one. As a result, such accounts are no longer eligible as deployment 
targets unless they are explicitly cleared.

However, prior to EIP-161, contracts were initialized with a nonce of
zero. This made it possible to end up with accounts that have:

- zero nonce
- empty runtime code
- non-empty storage (created during constructor execution)
- non-zero balance

These edge-case accounts complicate the storage emptiness check.

In practice, contract addresses are derived using one of the following
formulas:
- `Keccak256(rlp({sender, nonce}))[12:]`
- `Keccak256([]byte{0xff}, sender, salt[:], initHash)[12:]`

As such, an existing address is not selected as a deployment target
unless a collision occurs, which is extremely unlikely.

---

Previously, verifying storage emptiness relied on GetStorageRoot.
However, with the transition to the block-based access list (BAL), 
the storage root is no longer available, as computing it would require 
reconstructing the full storage trie from all mutations of preceding 
transactions.

To address this, this PR introduces a simplified approach: it hardcodes
the set of known accounts that have zero nonce, empty runtime code, 
but non-empty storage and non-zero balance. During contract deployment, 
if the destination address belongs to this set, the deployment is
rejected.

This check is applied retroactively back to genesis. Since no address
collision events have occurred in Ethereum’s history, this change does
not
alter existing behavior. Instead, it serves as a safeguard for future
state
transitions.
2026-04-14 15:54:36 +02:00
cui
2414861d36
core/state: optimize transient storage (#33695)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
Optimizes the transient storage. Turns it from a map of maps into a single map keyed by <account,slot>.
2026-04-14 15:39:42 +02:00
jvn
c690d6041e
cmd/geth: add Prague pruning points for hoodi (#34714)
Adds config to add Prague prune point for the hoodi testnet.
2026-04-14 14:58:27 +02:00
phrwlk
527ea11e50
core/vm/runtime: don't overwrite user input with default value (#33510)
runtime.setDefaults was unconditionally assigning cfg.Random =
&common.Hash{}, which silently overwrote any caller-provided Random
value. This made it impossible to simulate a specific PREVRANDAO and
also forced post-merge rules whenever London was active, regardless of
the intended environment.

This change only initializes cfg.Random when it is nil, matching how
other fields in Config are defaulted. Existing callers that did not set
Random keep the same behavior (a non-nil zero hash still enables
post-merge semantics), while callers that explicitly set Random now get
their value respected.
2026-04-13 15:46:13 +02:00
Daniel Liu
5b7511eeed
core/vm: include operand in error message (#34635)
Return ErrInvalidOpCode with the executing opcode and offending
immediate for forbidden DUPN, SWAPN, and EXCHANGE operands. Extend
TestEIP8024_Execution to assert both opcode and operand for all
invalid-immediate paths.
2026-04-13 14:13:33 +02:00
Guillaume Ballet
735bfd121a
trie/bintrie: spec change, big endian hashing of slot key (#34670)
The spec has been changed during SIC #49, the offset is encoded as a
big-endian number.
2026-04-13 09:42:37 +02:00
Marius van der Wijden
6333855163
core: turn gas into a vector <regularGas, stateGas> (#34691)
Pre-refactor PR to get 8037 upstreamed in chunks

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2026-04-13 14:09:42 +08:00
cui
ea5448814f
core/filtermaps: remove dead condition check (#34695)
already check on line 40 before.
2026-04-10 17:41:59 +02:00
Sina M
68c7058a80
core/stateless: fix parsing an empty witness (#34683)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
This is to fix a crasher in keeper.
2026-04-09 09:19:54 +08:00
Felföldi Zsolt
21b19362c2
core/state: fix tracer hook for EIP-7708 burn logs (#34688)
This PR fixes https://github.com/ethereum/go-ethereum/issues/34623 by
changing the `vm.StateDB` interface: 

Instead of `EmitLogsForBurnAccounts()` emitting burn logs, `LogsForBurnAccounts()
[]*types.Log` just returns these logs which are then emitted by the caller. 

This way when tracing is used, `hookedStateDB.AddLog` will be used 
automatically and there is no need to duplicate either the burn log
logic or the `OnLog` tracing hook.
2026-04-09 09:12:35 +08:00
DELENE-TCHIO
04e40995d9
core: merge access events for all system calls (#34637)
Some checks are pending
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Linux Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
ProcessBeaconBlockRoot (EIP-4788) and processRequestsSystemCall
(EIP-7002/7251) do not merge the EVM access events into the state after
execution. ProcessParentBlockHash (EIP-2935) already does this correctly
at line 290-291.

Without this merge, the Verkle witness will be missing the storage
accesses from the beacon root and request system calls, leading to
incomplete witnesses and potential consensus issues when Verkle
activates.
2026-04-07 21:55:09 +02:00
cui
0bafb29490
core/types: add accessList to WithSeal and WithBody (#34651)
Co-authored-by: Felix Lange <fjl@twurst.com>
2026-04-07 22:04:07 +08:00
rjl493456442
d8cb8a962b
core, eth, ethclient, triedb: report trienode index progress (#34633)
Some checks failed
/ Linux Build (push) Has been cancelled
/ Linux Build (arm) (push) Has been cancelled
/ Keeper Build (push) Has been cancelled
/ Windows Build (push) Has been cancelled
/ Docker Image (push) Has been cancelled
The trienode history indexing progress is also exposed via an RPC 
endpoint and contributes to the eth_syncing status.
2026-04-04 21:00:07 +08:00
Jonny Rhea
00da4f51ff
core, eth/protocols/snap: Snap/2 Protocol + BAL Serving (#34083)
Some checks failed
/ Linux Build (push) Has been cancelled
/ Linux Build (arm) (push) Has been cancelled
/ Keeper Build (push) Has been cancelled
/ Windows Build (push) Has been cancelled
/ Docker Image (push) Has been cancelled
Implement the snap/2 wire protocol with BAL serving

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2026-04-03 14:10:32 +08:00
rjl493456442
0ba4314321
core/state: introduce state iterator interface (#33102)
In this PR, the Database interface in `core/state` has been extended
with one more function:

```go
	// Iteratee returns a state iteratee associated with the specified state root,
	// through which the account iterator and storage iterator can be created.
	Iteratee(root common.Hash) (Iteratee, error)
```

With this additional abstraction layer, the implementation details can be hidden
behind the interface. For example, state traversal can now operate directly on 
the flat state for Verkle or binary trees, which do not natively support traversal.

Moreover, state dumping will now prefer using the flat state iterator as
the primary option, offering better efficiency.


Edit: this PR also fixes a tiny issue in the state dump, marshalling the
next field in the correct way.
2026-04-03 10:35:32 +08:00
cui
bcb0efd756
core/types: copy block access list hash in CopyHeader (#34636)
Some checks are pending
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Linux Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
2026-04-02 20:40:45 +08:00
CPerezz
3da517e239
core/state: fix storage counters in binary trie IntermediateRoot (#34110)
Add missing `StorageUpdated` and `StorageDeleted` counter increments
in the binary trie fast path of `IntermediateRoot()`.
2026-03-31 15:47:07 +02:00
Jonny Rhea
dc3794e3dc
core/rawdb: BAL storage layer (#34064)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
Add persistent storage for Block Access Lists (BALs) in `core/rawdb/`.
This provides read/write/delete accessors for BALs in the active
key-value store.

---------

Co-authored-by: Jared Wasinger <j-wasinger@hotmail.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2026-03-31 15:05:31 +08:00
Charles Dusek
e585ad3b42
core/rawdb: fix freezer dir.Sync() failure on Windows (#34115) 2026-03-30 15:34:23 +08:00
Daniel Liu
d1369b69f5
core/txpool/legacypool: use types.Sender instead of signer.Sender (#34059)
Some checks failed
/ Linux Build (arm) (push) Has been cancelled
/ Keeper Build (push) Has been cancelled
/ Windows Build (push) Has been cancelled
/ Linux Build (push) Has been cancelled
/ Docker Image (push) Has been cancelled
`pool.signer.Sender(tx)` bypasses the sender cache used by types.Sender,
which can force an extra signature recovery for every promotable tx
(promotion runs frequently). Use `types.Sender(pool.signer, tx)` here to
keep sender derivation cached and consistent.
2026-03-28 11:46:09 +01:00
rjl493456442
c3467dd8b5
core, miner, trie: relocate witness stats (#34106)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
This PR relocates the witness statistics into the witness itself, making
it more self-contained.
2026-03-27 17:06:46 +01:00
Lessa
8a3a309fa9
core/txpool/legacypool: remove redundant nil check in Get (#34092)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
Leftover from d40a255 when return type changed from *txpool.Transaction
to *types.Transaction.
2026-03-26 14:02:31 +01:00
bigbear
5d0e18f775
core/tracing: fix NonceChangeAuthorization comment (#34085)
Some checks failed
/ Linux Build (push) Has been cancelled
/ Linux Build (arm) (push) Has been cancelled
/ Keeper Build (push) Has been cancelled
/ Windows Build (push) Has been cancelled
/ Docker Image (push) Has been cancelled
Comment referenced NonceChangeTransaction which doesn't exist, should be
NonceChangeAuthorization.
2026-03-25 09:16:09 +01:00
Felföldi Zsolt
b87340a856
core, core/vm: implement EIP-7708 (#33645)
This PR implements EIP-7708 according to the latest "rough consensus":

https://github.com/ethereum/EIPs/pull/9003
https://github.com/etan-status/EIPs/blob/fl-ethlogs/EIPS/eip-7708.md

---------

Co-authored-by: Jared Wasinger <j-wasinger@hotmail.com>
Co-authored-by: raxhvl <raxhvl@users.noreply.github.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2026-03-23 22:29:53 +08:00
Daniel Liu
a61e5ccb1e
core, internal/ethapi: fix incorrect max-initcode RPC error mapping (#34067)
Problem:

The max-initcode sentinel moved from core to vm, but RPC pre-check
mapping still depended on core.ErrMaxInitCodeSizeExceeded. This mismatch
could surface inconsistent error mapping when oversized initcode is
submitted through JSON-RPC.

Solution:

- Remove core.ErrMaxInitCodeSizeExceeded from the core pre-check error
set.
- Map max-initcode validation errors in RPC from
vm.ErrMaxInitCodeSizeExceeded.
- Keep the RPC error code mapping unchanged (-38025).

Impact:

- Restores consistent max-initcode error mapping after the sentinel
move.
- Preserves existing JSON-RPC client expectations for error code -38025.
- No consensus, state, or protocol behavior changes.
2026-03-23 22:10:32 +08:00
Lessa
e23b0cbc22
core/rawdb: fix key length check for num -- hash in db inspect (#34074)
Fix incorrect key length calculation for `numHashPairings` in
`InspectDatabase`, introduced in #34000.

The `headerHashKey` format is `headerPrefix + num + headerHashSuffix`
(10 bytes), but the check incorrectly included `common.HashLength`,
expecting 42 bytes.

This caused all number -- hash entries to be misclassified as
unaccounted data.
2026-03-23 21:54:30 +08:00
CPerezz
77779d1098
core/state: bypass per-account updateTrie in IntermediateRoot for binary trie (#34022)
## Summary

In binary trie mode, `IntermediateRoot` calls `updateTrie()` once per
dirty account. But with the binary trie there is only one unified trie
(`OpenStorageTrie` returns `self`), so each call redundantly does
per-account trie setup: `getPrefetchedTrie`, `getTrie`, slice
allocations for deletions/used, and `prefetcher.used` — all for the same
trie pointer.

This PR replaces the per-account `updateTrie()` calls with a single flat
loop that applies all storage updates directly to `s.trie`. The MPT path
is unchanged. The prefetcher trie replacement is guarded to avoid
overwriting the binary trie that received updates.

This is the phase-1 counterpart to #34021 (H01). H01 fixes the commit
phase (`trie.Commit()` called N+1 times). This PR fixes the update phase
(`updateTrie()` called N times with redundant setup). Same root cause —
unified binary trie operated on per-account — different phases.

## Benchmark (Apple M4 Pro, 500K entries, `--benchtime=10s --count=3`,
on top of #34021)

| Metric | H01 baseline | H01 + this PR | Delta |
|--------|:------------:|:-------------:|:-----:|
| Approve (Mgas/s) | 368 | **414** | **+12.5%** |
| BalanceOf (Mgas/s) | 870 | 875 | +0.6% |

Should be rebased after #34021 is merged.
2026-03-20 15:40:04 +01:00
jwasinger
fd859638bd
core/vm: rework gas measurement for call variants (#33648)
EIP-7928 brings state reads into consensus by recording accounts and storage accessed during execution in the block access list. As part of the spec, we need to check that there is enough gas available to cover the cost component which doesn't depend on looking up state. If this component can't be covered by the available gas, we exit immediately.

The portion of the call dynamic cost which doesn't depend on state look ups:

- EIP2929 call costs
- value transfer cost
- memory expansion cost

This PR:

- breaks up the "inner" gas calculation for each call variant into a pair of stateless/stateful cost methods
- modifies the gas calculation logic of calls to check stateless cost component first, and go out of gas immediately if it is not covered.

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
2026-03-19 10:02:49 -06:00
Sina M
6ae3f9fa56
core/history: refactor pruning configuration (#34036)
This PR introduces a new type HistoryPolicy which captures user intent
as opposed to pruning point stored in the blockchain which persists the
actual tail of data in the database.

It is in preparation for the rolling history expiry feature.

It comes with a semantic change: if database was pruned and geth is
running without a history mode flag (or explicit keep all flag) geth
will emit a warning but continue running as opposed to stopping the
world.
2026-03-18 13:54:29 +01:00
Mayveskii
b6115e9a30
core: fix txLookupLock mutex leak on error returns in reorg() (#34039)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run
2026-03-18 15:43:24 +08:00