IS-1459 Fix Berlin replay state-root compatibility and DB usage recovery#2482
Merged
Conversation
|
SUGGESTIONS BEFORE MERGE:
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates transaction RLP decoding to incorporate BerlinForkPatch state, aiming to make Berlin-era replay behavior deterministic (notably around access-list parsing / downstream warm-cold accounting), by threading a Berlin flag through Transaction/TransactionBase construction and using it during access-list validation.
Changes:
- Add a
_berlinForkPatchEnabledflag toTransactionandTransactionBaseconstructors and propagate it through major transaction-decode call sites (RPC, txqueue, block import, host, precompiles, etc.). - Gate strict EIP-2930 access-list address/storage-key length validation behind
BerlinForkPatchduring typed-transaction decoding.
Findings (sorted by severity)
- Critical:
eth_inspectTransactionis currently passing patch flags in the wrong argument positions toTransaction(...), which can inadvertently enableallowInvalidand disable intended patch flags. - Medium:
StateProgressLog::loadProgressData()decodes stored CTX transactions usingisEnabledInWorkingBlock()instead of the persisteddata.timestamp, which can mis-decode transactions when crash recovery occurs across a patch activation boundary.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| libweb3jsonrpc/Eth.cpp | Passes Berlin patch flag into RPC transaction decoding (but currently has a critical argument-order bug in eth_inspectTransaction). |
| libskale/StateProgressLog.cpp | Adds Berlin patch flag to crash-recovery CTX decoding (should key off persisted timestamp, not working-block state). |
| libethereum/TransactionQueue.cpp | Threads Berlin patch enable into txpool import/verification decoding. |
| libethereum/Transaction.h | Extends Transaction constructor signature with _berlinForkPatchEnabled. |
| libethereum/Transaction.cpp | Forwards Berlin patch enable flag into TransactionBase. |
| libethereum/SkaleHost.cpp | Threads Berlin patch enable into broadcast/regular/CTX transaction decoding. |
| libethereum/Precompiled.cpp | Threads Berlin patch enable into precompile-created transaction decoding. |
| libethereum/ClientBase.cpp | Threads Berlin patch enable into historical transaction decoding keyed by block timestamp. |
| libethereum/BlockChain.cpp | Threads Berlin patch enable into block verification and pending CTX decoding keyed by timestamp. |
| libethcore/TransactionBase.h | Extends TransactionBase ctor and typed-decode helpers with _berlinForkPatchEnabled. |
| libethcore/TransactionBase.cpp | Uses _berlinForkPatchEnabled to gate strict access-list entry length validation during typed-tx decoding. |
Comment on lines
157
to
161
| dev::eth::Transaction tx( item[0].data(), dev::eth::CheckTransaction::None, true, | ||
| EIP1559TransactionsPatch::isEnabledInWorkingBlock(), | ||
| InvalidTransactionFormatPatch::isEnabledInWorkingBlock(), | ||
| BerlinForkPatch::isEnabledInWorkingBlock(), | ||
| Bite2Patch::isEnabledInWorkingBlock() ); |
kladkogex
approved these changes
Jun 5, 2026
DmytroNazarenko
approved these changes
Jun 5, 2026
Comment on lines
+71
to
+80
| os.environ["HARDFORK_COMPAT_CFG_JSON"] = cfg_file | ||
| pytest.main( | ||
| [ | ||
| str(SUITE_DIR / "test_hardfork_compat.py"), | ||
| "-v", | ||
| "--tb=short", | ||
| "-p", "no:cacheprovider", | ||
| ], | ||
| plugins=[collector], | ||
| ) |
PropzSaladaz
approved these changes
Jun 5, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Description
Fixed a Berlin fork replay compatibility issue where EIP-2929 access sets could be initialized at the wrong time or with incomplete data, especially around contract creation. This caused 5.2.0 to replay some 5.1.0-produced blocks with different warm/cold access
accounting, leading to gas/receipt differences and potential state-root mismatches.
Also fixed pieceUsageBytes handling for block DB rotation accounting. The value could be missing or incorrect, causing storage/rotation logic to use bad accounting data instead of recovering it from existing block/extras DB contents.
Tests
Validated with hardfork compatibility replay focused on 5.1.0-produced blocks replayed by 5.2.0, including blocks containing legacy, Type1/Type2, contract deployment, and CREATE/CREATE2 transactions.
Also verified that the Berlin fork path no longer produces state-root mismatches during replay.
Performance Impact
No expected runtime performance regression.
The Berlin fix affects per-transaction access-set initialization/restoration only in Berlin-enabled execution paths. The pieceUsageBytes fix affects DB accounting/recovery and rotation bookkeeping, not normal EVM execution. No benchmarks were required.