Skip to content

internal/ethapi: support for beacon root and withdrawals in simulate api #31304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Mar 24, 2025

Conversation

rezbera
Copy link
Contributor

@rezbera rezbera commented Mar 1, 2025

Addresses #31264

@rezbera rezbera requested review from fjl, s1na and lightclient as code owners March 1, 2025 20:59
@@ -267,20 +276,22 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
// EIP-7251
core.ProcessConsolidationQueue(&requests, evm)
}
header.Root = sim.state.IntermediateRoot(true)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Root calculation moved to the end, i.e. after withdrawals since they change state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Update: Root Calculation is now done in FinalizeAndAssemble

Comment on lines -271 to -278
header.GasUsed = gasUsed
if sim.chainConfig.IsCancun(header.Number, header.Time) {
header.BlobGasUsed = &blobGasUsed
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

gas and blob setting moved up, i.e. closer to where gasUsed and blobGasUsed are last used

@rezbera rezbera marked this pull request as draft March 1, 2025 21:17
Comment on lines 292 to 295
if block.BlockOverrides.Withdrawals != nil {
// We assume that if the user provides Withdrawals, we're operating on Beacon consensus
// which can have nil ChainHeadReader
sim.b.Engine().Finalize(nil, header, sim.state, blockBody)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a better way to do this? e.g. create a ChainHeadReader (seems non-trivial)

Copy link
Contributor

Choose a reason for hiding this comment

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

I like your idea of using Finalize here. I think we can take it a step further and use FinalizeAndAssemble. Would you be up for doing it? otherwise I will submit a follow-up PR.

I would not assume anything about the beacon engine tho. User can still provide withdrawal and request it to be based on a pre-shanghai block. This can crash the node. Please mock the chainHeaderReader. All of those methods are available on the backend so it should be straightforward.

@rezbera rezbera marked this pull request as ready for review March 1, 2025 21:39
Update simulate.go

Update simulate.go

Update simulate.go

Update consensus.go

passed withdrawals - now state root mismartch

working but withdrawals issue

Added support
@rezbera rezbera force-pushed the enhance-simulation-api branch from fb1dd96 to 2407255 Compare March 1, 2025 21:40
}
if requests != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved up, closer where requests is calculated

@phearnot
Copy link

phearnot commented Mar 3, 2025

Hey @rezbera, we also need withdrawal support in simulateV1 for our project. I've tweaked it like so. My idea was to handle withdrawals in the same way as they are handled in the "real" engine. State root hash is adjusted when address balance changes, so there's no need to manually change it.
I've run some smoke tests against my patch. I was able to pass the block with withdrawals generated by simulateV1 to newPayload/forkchoiceUpdated, and everything seemed to work fine.

@rezbera
Copy link
Contributor Author

rezbera commented Mar 3, 2025

Hey @rezbera, we also need withdrawal support in simulateV1 for our project. I've tweaked it like so. My idea was to handle withdrawals in the same way as they are handled in the "real" engine. State root hash is adjusted when address balance changes, so there's no need to manually change it. I've run some smoke tests against my patch. I was able to pass the block with withdrawals generated by simulateV1 to newPayload/forkchoiceUpdated, and everything seemed to work fine.

Good call, that could work as well and avoids the need to deal with consensus engine but also not a fan of duplicating logic like that. Will see was maintainers think

@rezbera
Copy link
Contributor Author

rezbera commented Mar 15, 2025

Anything I can do to support getting this through @s1na ?

@s1na
Copy link
Contributor

s1na commented Mar 17, 2025

Sorry for not getting to this earlier. If you update it based on the above comment it's good to go 💯

if sim.chainConfig.IsCancun(header.Number, header.Time) {
header.BlobGasUsed = &blobGasUsed
}
var withdrawals types.Withdrawals
Copy link
Contributor Author

Choose a reason for hiding this comment

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

withdrawals are now managed in FinalizeAndAssemble

return m.Backend.CurrentHeader()
}

func (m *simChainHeadReader) GetHeader(hash common.Hash, number uint64) *types.Header {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

noting that there doesn't seem to be a clear standard as to whether to ignore hash or number, so going with hash instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

HeaderByHash can also return non-canonical blocks. That's the reason for GetHeader existing. It asks for a block at a particular height with a assumed hash.

So we can improve this here by doing HeaderByNumber first and double-checking the hash.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I apppreciate the additional context. I've updated as suggested

@rezbera
Copy link
Contributor Author

rezbera commented Mar 18, 2025

Sorry for not getting to this earlier. If you update it based on the above comment it's good to go 💯

Thanks for the review @s1na ! I've updated as requested - let me know if you'd like any further modifications

if requests != nil {
reqHash := types.CalcRequestsHash(requests)
header.RequestsHash = &reqHash
}
b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil))

blockBody := &types.Body{Transactions: txes, Withdrawals: *block.BlockOverrides.Withdrawals}
Copy link
Contributor

Choose a reason for hiding this comment

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

this can panic that's why tests are failing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you - have addressed this by checking withdrawals in sanitizeChain

@@ -346,6 +389,9 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) {
n := new(big.Int).Add(prevNumber, big.NewInt(1))
block.BlockOverrides.Number = (*hexutil.Big)(n)
}
if block.BlockOverrides.Withdrawals == nil {
block.BlockOverrides.Withdrawals = &types.Withdrawals{}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noting that we do an empty slice rather than nil, which semantically is fine as checks in consensus are done as length checks rather than nil checks.

	if len(body.Withdrawals) > 0 {
		return nil, errors.New("clique does not support withdrawals")
	}

s1na
s1na previously approved these changes Mar 21, 2025
Copy link
Contributor

@s1na s1na left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@s1na
Copy link
Contributor

s1na commented Mar 21, 2025

Thanks for the quick responses and bringing this so far. I was about to merge this before I realized two things:

  • We are not replacing the header's parentBeaconRoot value with that of the override (should prob do in MakeHeader)
  • Adding these fields to BlockOverride means that users can set them also for eth_call variants. I don't want to stretch this PR more by changing those methods too. But we should at least change BlockOverride.Apply to return an error in case BeaconRoot or Withdrawals are set to indicate lack of support

@rezbera
Copy link
Contributor Author

rezbera commented Mar 22, 2025

Thanks for the quick responses and bringing this so far. I was about to merge this before I realized two things:

  • We are not replacing the header's parentBeaconRoot value with that of the override (should prob do in MakeHeader)
  • Adding these fields to BlockOverride means that users can set them also for eth_call variants. I don't want to stretch this PR more by changing those methods too. But we should at least change BlockOverride.Apply to return an error in case BeaconRoot or Withdrawals are set to indicate lack of support

Great catch. I've addressed this. Happy to fix any other concerns or nits

Copy link
Contributor

@s1na s1na left a comment

Choose a reason for hiding this comment

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

Thanks it's a good one

@s1na s1na merged commit 71e9c9b into ethereum:master Mar 24, 2025
3 of 4 checks passed
@s1na s1na added this to the 1.15.6 milestone Mar 24, 2025
sidhujag pushed a commit to syscoin/go-ethereum that referenced this pull request Mar 26, 2025
…api (ethereum#31304)

Adds block override fields for beacon block root and withdrawals to the eth_simulateV1.
Addresses ethereum#31264
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.

3 participants