Skip to content

PIP-74: state-sync txs inclusion#1726

Merged
manav2401 merged 40 commits intodevelopfrom
lmartins/state-sync-txs-on-block-body
Oct 30, 2025
Merged

PIP-74: state-sync txs inclusion#1726
manav2401 merged 40 commits intodevelopfrom
lmartins/state-sync-txs-on-block-body

Conversation

@lucca30
Copy link
Copy Markdown
Contributor

@lucca30 lucca30 commented Aug 27, 2025

Description

Implements Canonical Inclusion of StateSync Transactions in Block Bodies.
This change introduces a new typed system transaction (StateSyncTx) appended to blocks that execute StateSync events. The transaction itself has zero gas/fees and does not run EVM code, but anchors all StateSync outcomes into the canonical transaction/receipt set.

Key Effects

  • Commits StateSync membership and results to transactionsRoot, receiptsRoot, and logsBloom.
  • Provides canonical receipts and logs for observability (PIP-20) and replay semantics (PIP-36).
  • Enables trustless snap-sync and consistent validation of StateSync execution.
  • Requires a hard fork, as block roots and hashing change post-fork.

This proposal improves proofs, observability, and simplicity while maintaining economic neutrality and execution semantics.

Changes

  • Bugfix (non-breaking change that solves an issue)
  • Hotfix (change that solves an urgent issue, and requires immediate attention)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (change that is not backwards-compatible and/or changes current functionality)
  • Changes only for a subset of nodes

Breaking changes

It's a hardfork, so it demands stablishing a block where it starts.

@lucca30 lucca30 marked this pull request as ready for review September 29, 2025 17:11
@codecov
Copy link
Copy Markdown

codecov bot commented Oct 9, 2025

Codecov Report

❌ Patch coverage is 31.63265% with 134 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.70%. Comparing base (c1e1773) to head (0b556fa).
⚠️ Report is 293 commits behind head on develop.

Files with missing lines Patch % Lines
consensus/bor/bor.go 10.00% 52 Missing and 2 partials ⚠️
core/types/tx_state_sync.go 51.61% 26 Missing and 4 partials ⚠️
core/parallel_state_processor.go 0.00% 12 Missing ⚠️
consensus/beacon/consensus.go 0.00% 11 Missing ⚠️
consensus/ethash/consensus.go 0.00% 6 Missing ⚠️
core/state_processor.go 58.33% 3 Missing and 2 partials ⚠️
core/blockchain.go 0.00% 1 Missing and 2 partials ⚠️
core/chain_makers.go 50.00% 3 Missing ⚠️
core/types/transaction_signing.go 0.00% 2 Missing and 1 partial ⚠️
core/state/statedb_hooked.go 0.00% 2 Missing ⚠️
... and 3 more
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1726      +/-   ##
===========================================
- Coverage    48.19%   47.70%   -0.49%     
===========================================
  Files          827      840      +13     
  Lines       135906   142707    +6801     
===========================================
+ Hits         65497    68076    +2579     
- Misses       66182    70181    +3999     
- Partials      4227     4450     +223     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@manav2401
Copy link
Copy Markdown
Member

The core logic LGTM. There are a few places where we might have to make changes.

  1. There are certain RPC methods which has custom logic for handling bor events. After this PR, we will have to maintain 2 separate logic (the post HF one would be very simple).
  2. Right now we use a separate transaction lookup which maps a transaction hash to bor receipt. That logic won't be used after HF. We need to confirm if queries done via tx hash works correctly or not (e.g. getTransactionReceipt by transaction hash). Ideally they should as the lookup entries are updated by iterating over block.Transactions which already has state-sync transactions.
  3. There will be some issues w/ snap sync post this HF as my changes related to eth/69 are merged. For e.g. right now, we exclude state-sync receipt from receipt root calculation but after the HF, we should be including it. If you want, I can take a look into this as I am mostly familiar with where the changes would be.
    Thanks!

@lucca30
Copy link
Copy Markdown
Contributor Author

lucca30 commented Oct 9, 2025

Thanks for the comments @manav2401

  1. There are certain RPC methods which has custom logic for handling bor events. After this PR, we will have to maintain 2 separate logic (the post HF one would be very simple).

I think I already checked all of them and just eth_getTransactionByHash showed an issue but not directly related to it. But it's crucial checking all of them specially on e2e.

  1. Right now we use a separate transaction lookup which maps a transaction hash to bor receipt. That logic won't be used after HF. We need to confirm if queries done via tx hash works correctly or not (e.g. getTransactionReceipt by transaction hash). Ideally they should as the lookup entries are updated by iterating over block.Transactions which already has state-sync transactions.
    Yeah, they not impact
  1. There will be some issues w/ snap sync post this HF as my changes related to eth/69 are merged. For e.g. right now, we exclude state-sync receipt from receipt root calculation but after the HF, we should be including it. If you want, I can take a look into this as I am mostly familiar with where the changes would be.

Yes, it will demands a HF check. As soon as one of the PR's got merged we can fix on the other one.

* eth: include bor receipts in ReceiptHash post HF

* eth: rename to receiptListHash

* eth: extrat typecasting logic for better testing, fix type matching issue

* eth: add e2e tests for receipt delivery

* eth/protocols/eth: apply HF logic while handling receipt query over eth69

* core: skip split receipts post HF

* tests/bor: extend e2e test to check presence of state-sync in block
@manav2401
Copy link
Copy Markdown
Member

The core logic LGTM. There are a few places where we might have to make changes.

  1. There are certain RPC methods which has custom logic for handling bor events. After this PR, we will have to maintain 2 separate logic (the post HF one would be very simple).
  2. Right now we use a separate transaction lookup which maps a transaction hash to bor receipt. That logic won't be used after HF. We need to confirm if queries done via tx hash works correctly or not (e.g. getTransactionReceipt by transaction hash). Ideally they should as the lookup entries are updated by iterating over block.Transactions which already has state-sync transactions.
  3. There will be some issues w/ snap sync post this HF as my changes related to eth/69 are merged. For e.g. right now, we exclude state-sync receipt from receipt root calculation but after the HF, we should be including it. If you want, I can take a look into this as I am mostly familiar with where the changes would be.
    Thanks!

All 3 things seems to handled. First one is pending to be merged and needs some e2e and devnet testing.

manav2401 and others added 5 commits October 21, 2025 20:32
* fix: append tx only in FinalizeAndAssemble and use state instead of wrappedState

* consensus/bor: sort logs before extracting state-sync logs

* chore: revert statedb changes

---------

Co-authored-by: Manav Darji <manavdarji.india@gmail.com>
@marcello33 marcello33 requested a review from a team October 24, 2025 09:47
@kamuikatsurgi kamuikatsurgi requested a review from Copilot October 24, 2025 10:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements canonical inclusion of StateSync transactions in block bodies by introducing a new typed system transaction (StateSyncTx). After a hard fork activation, StateSync events are appended as transactions in block bodies, making them part of the canonical transaction/receipt sets. This allows StateSync outcomes to be committed to transactionsRoot, receiptsRoot, and logsBloom, improving observability, replay semantics, and enabling trustless snap-sync.

Key changes:

  • Introduces StateSyncTxType (0x7f) and StateSyncTx transaction type that carries StateSync data
  • Modifies consensus engine methods to return updated receipts from Finalize and FinalizeAndAssemble
  • Updates P2P receipt handling to conditionally include/exclude StateSync receipts based on hard fork activation

Reviewed Changes

Copilot reviewed 34 out of 35 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
core/types/tx_state_sync.go Implements the new StateSyncTx transaction type with encoding/decoding logic
core/types/state_data.go Changes StateSyncData.Data from string to []byte for binary data handling
consensus/bor/bor.go Appends StateSyncTx to block body post-fork and generates corresponding receipts
consensus/consensus.go Updates Engine interface to return receipts from Finalize/FinalizeAndAssemble
eth/protocols/eth/handlers.go Adjusts P2P receipt serving to handle StateSync receipts based on fork activation
internal/ethapi/api.go Skips separate BorReceipt fetching post-fork since they're in normal receipts
params/config.go Adds StateSyncBlock configuration field for hard fork activation

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@kamuikatsurgi kamuikatsurgi changed the title StateSync Tx on Body PIP-74: state-sync txs inclusion Oct 27, 2025
@kamuikatsurgi kamuikatsurgi added the squash and merge This PR will be squashed and merged label Oct 27, 2025
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
5.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@manav2401 manav2401 merged commit 37438e4 into develop Oct 30, 2025
8 of 13 checks passed
@kamuikatsurgi kamuikatsurgi deleted the lmartins/state-sync-txs-on-block-body branch October 30, 2025 17:43
marcello33 added a commit that referenced this pull request Nov 17, 2025
* Parallel block import (#1662)

* core: naive first implmenetation of parallel block import in InsertChainStateless

* core: add logic to handle dependency while parallel import

* core: handle unknown ancestor + init some UTs

* core: implement alternative way to check for unknown ancestor

* core: defer ValidateWitnessPreState

* zero commit

* core: do sequential insert if the importing chain is small

* core: fix  error handling

* core: update UTs

* core,eth,internal/cli: add config to enable/disable parallel import + refactor

* core: add metrics for seq and parallel import

* internal/cli: moved parallelstatelessimport flag to the witness config

* core: changed debug import log to info

* core: added 2 new metrics to track the number of blocks processed in sequential and parallel stateless imports

* core: init benchmarks

* core: fix benchmarks

* core: use worker pool for parallel block import

* core: try parallel import for smaller batch

* core: dedup header verification logic

* zero commit

* core,eth,internal/cli: improvements based on comments

* core: add adversarial tests for stateless insert

* core: re-add empty chain insertion case

* zero commit to trigger CI

* core,eth/catalyst: report correct execution stats for stateless insert

* CI: temp update for running stateless tests

* zero commit to trigger CI

* zero commit to trigger CI

* CI: try running on stateless branch

* Revert "CI: try running on stateless branch"

This reverts commit 98b5704.

* zero commit to trigger CI

* core: add log for deferred exec of blocks due to invalid root err in parallel import

* core: changed log to debug

* core,eth,internal/ethapi: suppress error log for state sync when parallel import is enabled

* eth/filters: fix gomock

* eth: add missing configs

* core: retry execution in parallel import for block validator errors

* core: commit block before retrying failed execution

* core: rm redundant witness in execResult

* core: try flushing state db asap post execution

* core: add temp log when committing code

* core: enable retry for first block in batch

* Revert "core: add temp log when committing code"

This reverts commit cf63cc3.

* core: cap workers spun

* Revert "core: cap workers spun"

This reverts commit 96367ee.

* core: ensure statedb cleanup

* core: add temp debug logs

* core: add temp debug logs

* core: add temp log to track sidechain

* core: add temp log for contract code in commitAndFlush

* core: add retry for all processing and internal state db errors

* core: add state db error validation during deferred exec

* core: add TestParallelStateless_ContractDeployedThenCalled

* Revert "core: add temp log for contract code in commitAndFlush"

This reverts commit 174765f.

* Revert "core: add temp log to track sidechain"

This reverts commit 29b3366.

* Revert "core: add temp debug logs"

This reverts commit 2c4f840.

* internal/cli: turn off parallel import by default

* internal/cli: update flag identation

* CI: update comment

* zero commit to trigger CI

* internal/cli: rm witness prune flags

---------

Co-authored-by: Pratik Patil <pratikspatil024@gmail.com>

* emit event when write block in stateless node (#1840)

* Address Biased Trie Cache (#1837)

* Address-biased trie cache

* Stop preload early

* Print more stats

* Increase cache size

* Store by depth

* More customizable

* Add metrics

* Fix key format

* Async preload

* Simplify

* Fix linter

* Allow interrupt

* Remove free disk step in CI (#1843)

Remove this step since the runner has 600G of disk space.

* chore: bump kurtosis-pos (#1845)

* chore: bump kurtosis-pos

* chore: bump to v1.2.1

* PIP-74: state-sync txs inclusion (#1726)

* first working version of new state sync tx

* remove logs

* fix lint

* fix integration tests

* test fixes

* lint fix

* fix parallel processor

* type improvement and unit tests

* remove duplicates

* ignore data test output

* fixing method calls and fields

* build fix

* remove bor filter for after hf blocks

* sort logs just when necessary

* ssTxs: fix receiptsHash mismatch (#1829)

* ssTxs: fix receiptsHash mismatch

* chore: remove block hash and number

* revert: add block number

* core(tx): fix Hash method for StateSyncTxType (#1830)

* eth: fixes in receipt handling via p2p post HF (#1825)

* eth: include bor receipts in ReceiptHash post HF

* eth: rename to receiptListHash

* eth: extrat typecasting logic for better testing, fix type matching issue

* eth: add e2e tests for receipt delivery

* eth/protocols/eth: apply HF logic while handling receipt query over eth69

* core: skip split receipts post HF

* tests/bor: extend e2e test to check presence of state-sync in block

* core/types: return nil for chainID() call over state-sync tx

* internal/ethapi: handle bor txs and receipts post HF (#1834)

* fix: cumulativeGasUsed in insertStateSyncTransactionAndCalculateReceipt (#1835)

* fix: sort logs and remove duplicate append in Finalize (#1836)

* fix: append tx only in FinalizeAndAssemble and use state instead of wrappedState

* consensus/bor: sort logs before extracting state-sync logs

* chore: revert statedb changes

---------

Co-authored-by: Manav Darji <manavdarji.india@gmail.com>

* chore: nit (#1838)

* chore: typos

* fix: lint

* Renaming to Madhugiri HF

* chore: nits

* (fix): handle pointers to receipt list received via p2p

* (chore): rename tests with HF name

* chore: more nits

* core: add blocktime in bor receipt logs (#1848)

* core/types: derive bloom for bor receipts

---------

Co-authored-by: kamuikatsurgi <shahkrishang11@gmail.com>
Co-authored-by: Krishang Shah <109511742+kamuikatsurgi@users.noreply.github.com>
Co-authored-by: Manav Darji <manavdarji.india@gmail.com>

* core, miner, params, cmd: implement EIP-7823, EIP-7825 and EIP-7883 (#1842)

* first working version of new state sync tx

* remove logs

* fix lint

* fix integration tests

* test fixes

* lint fix

* fix parallel processor

* type improvement and unit tests

* remove duplicates

* ignore data test output

* fixing method calls and fields

* build fix

* remove bor filter for after hf blocks

* sort logs just when necessary

* ssTxs: fix receiptsHash mismatch (#1829)

* ssTxs: fix receiptsHash mismatch

* chore: remove block hash and number

* revert: add block number

* core(tx): fix Hash method for StateSyncTxType (#1830)

* eth: fixes in receipt handling via p2p post HF (#1825)

* eth: include bor receipts in ReceiptHash post HF

* eth: rename to receiptListHash

* eth: extrat typecasting logic for better testing, fix type matching issue

* eth: add e2e tests for receipt delivery

* eth/protocols/eth: apply HF logic while handling receipt query over eth69

* core: skip split receipts post HF

* tests/bor: extend e2e test to check presence of state-sync in block

* core/types: return nil for chainID() call over state-sync tx

* internal/ethapi: handle bor txs and receipts post HF (#1834)

* fix: cumulativeGasUsed in insertStateSyncTransactionAndCalculateReceipt (#1835)

* fix: sort logs and remove duplicate append in Finalize (#1836)

* fix: append tx only in FinalizeAndAssemble and use state instead of wrappedState

* consensus/bor: sort logs before extracting state-sync logs

* chore: revert statedb changes

---------

Co-authored-by: Manav Darji <manavdarji.india@gmail.com>

* chore: nit (#1838)

* chore: typos

* fix: lint

* Renaming to Madhugiri HF

* chore: nits

* (fix): handle pointers to receipt list received via p2p

* (chore): rename tests with HF name

* chore: more nits

* core: implement eip7883

* core: implement eip7825

* fix lint

* fix isOsaka condition

* fix lint and add comment for int test failing

* fix failing test / address comments

* core: add blocktime in bor receipt logs (#1848)

* core/types: derive bloom for bor receipts

* prioritize ss hf / remove todo

* fix lint

* split precompiled contracts and addresses for madhugiri HF from osaka

* revert err msg to align with geth

* eth/gasestimator: check ErrGasLimitTooHigh conditions (#32348)

This PR makes 2 changes to how
[EIP-7825](ethereum/go-ethereum#31824) behaves.

When `eth_estimateGas` or `eth_createAccessList` is called without any
gas limit in the payload, geth will choose the block's gas limit or the
`RPCGasCap`, which can be larger than the `maxTxGas`.

When this happens for `estimateGas`, the gas estimation just errors out
and ends, when it should continue doing binary search to find the lowest
possible gas limit.

This PR will: 
- Add a check to see if `hi` is larger than `maxTxGas` and cap it to
`maxTxGas` if it's larger. And add a special case handling for gas
estimation execute when it errs with `ErrGasLimitTooHigh`

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>

* internal/ethapi: skip tx gas limit check for calls (#32641)

This disables the tx gaslimit cap for eth_call and related RPC operations.

I don't like how this fix works. Ideally we'd be checking the tx
gaslimit somewhere else, like in the block validator, or any other place
that considers block transactions. Doing the check in StateTransition
means it affects all possible ways of executing a message.

The challenge is finding a place for this check that also triggers
correctly in tests where it is wanted. So for now, we are just combining
this with the EOA sender check for transactions. Both are disabled for
call-type messages.

* internal/ethapi: use gas from gaspool for call defaults

* eth/gasestimator: check for madhugiri HF

* consensus/bor: honour MaxTxGas for system calls

---------

Co-authored-by: Lucca Martins <lucca_martins30@yahoo.com.br>
Co-authored-by: kamuikatsurgi <shahkrishang11@gmail.com>
Co-authored-by: Krishang Shah <109511742+kamuikatsurgi@users.noreply.github.com>
Co-authored-by: Manav Darji <manavdarji.india@gmail.com>
Co-authored-by: Minhyuk Kim <kimminhyuk1004@gmail.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>

* (chore): update madhugiri block number for amoy and update consensus block time (#1851)

* first working version of new state sync tx

* remove logs

* fix lint

* fix integration tests

* test fixes

* lint fix

* fix parallel processor

* type improvement and unit tests

* remove duplicates

* ignore data test output

* fixing method calls and fields

* build fix

* remove bor filter for after hf blocks

* sort logs just when necessary

* ssTxs: fix receiptsHash mismatch (#1829)

* ssTxs: fix receiptsHash mismatch

* chore: remove block hash and number

* revert: add block number

* core(tx): fix Hash method for StateSyncTxType (#1830)

* eth: fixes in receipt handling via p2p post HF (#1825)

* eth: include bor receipts in ReceiptHash post HF

* eth: rename to receiptListHash

* eth: extrat typecasting logic for better testing, fix type matching issue

* eth: add e2e tests for receipt delivery

* eth/protocols/eth: apply HF logic while handling receipt query over eth69

* core: skip split receipts post HF

* tests/bor: extend e2e test to check presence of state-sync in block

* core/types: return nil for chainID() call over state-sync tx

* internal/ethapi: handle bor txs and receipts post HF (#1834)

* fix: cumulativeGasUsed in insertStateSyncTransactionAndCalculateReceipt (#1835)

* fix: sort logs and remove duplicate append in Finalize (#1836)

* fix: append tx only in FinalizeAndAssemble and use state instead of wrappedState

* consensus/bor: sort logs before extracting state-sync logs

* chore: revert statedb changes

---------

Co-authored-by: Manav Darji <manavdarji.india@gmail.com>

* chore: nit (#1838)

* chore: typos

* fix: lint

* Renaming to Madhugiri HF

* chore: nits

* (fix): handle pointers to receipt list received via p2p

* (chore): rename tests with HF name

* chore: more nits

* core: add blocktime in bor receipt logs (#1848)

* core/types: derive bloom for bor receipts

* (chore): update madhugiri block for amoy

* Change consensus block time to 1s at Madhugiri HF (#1852)

---------

Co-authored-by: Lucca Martins <lucca_martins30@yahoo.com.br>
Co-authored-by: kamuikatsurgi <shahkrishang11@gmail.com>
Co-authored-by: Krishang Shah <109511742+kamuikatsurgi@users.noreply.github.com>
Co-authored-by: Jerry <jerrycgh@gmail.com>

* Completed reset prefetcher (#1853)

* internal/ethapi: restore original RPC gas cap (#1856)

* Restore original RPC gas cap

* Fix test

* chore: fix wrong function name in comment (#1841)

Signed-off-by: reddaisyy <reddaisy@outlook.jp>

* Revert "(chore): update madhugiri block number for amoy and update consensus block time (#1851)" (#1857)

This reverts commit 103f1f4.

* params: bump version to v2.4.0-beta

* Dont OpenTrie because HistoricDatabase doesnt implement trie (#1858)

* chore: use 2^25 as the MaxTxGas (#1859)

* params: bump version to v2.4.0-beta2

* chore: set madhugiri block for amoy and consensus block time (#1867)

* chore: set madhugiri block for amoy and consensus block time

* params: bump version

* Disable txn indexer in stateless mode

Since stateless nodes are using a different pruner from the regular pruner in geth, the transaction indexer will have problem with pruned blocks, resulting hanging goroutines in memory. This change prevents stateless node from running indexer on pruned blocks.

* core: init PrecompiledAddressesMadhugiri

* params: bump version

* params: bump version for stable release

* chore: set madhugiri block for mainnet and consensus block time

* chore: fix lint

* Include missing check of P256 on Amoy (#1877)

* checks p256 instruction

* lint fix

* v2.5.0 candidate (#1878)

* chore: MadhugiriPro hf

* params: use stable tag

* chore: set new HF heights

* Reinforce Precompile Check on any new HF (#1881)

* Include missing check of P256 on Amoy (#1877)

* checks p256 instruction

* lint fix

* reinforce precompilers check

---------

Co-authored-by: Lucca Martins <lucca_martins30@yahoo.com.br>

---------

Signed-off-by: reddaisyy <reddaisy@outlook.jp>
Co-authored-by: Raneet Debnath <35629432+Raneet10@users.noreply.github.com>
Co-authored-by: Pratik Patil <pratikspatil024@gmail.com>
Co-authored-by: Lucca Martins <lucca_martins30@yahoo.com.br>
Co-authored-by: Jerry <jerrycgh@gmail.com>
Co-authored-by: Krishang Shah <109511742+kamuikatsurgi@users.noreply.github.com>
Co-authored-by: kamuikatsurgi <shahkrishang11@gmail.com>
Co-authored-by: Manav Darji <manavdarji.india@gmail.com>
Co-authored-by: Minhyuk Kim <kimminhyuk1004@gmail.com>
Co-authored-by: Gary Rong <garyrong0905@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
Co-authored-by: reddaisyy <reddaisy@outlook.jp>
Co-authored-by: Angel Valkov <avalkov@polygon.technology>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

squash and merge This PR will be squashed and merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants