mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
internal/ethapi: fix withdrawal regression in eth_simulateV1 (#34939)
Fixes the regression caught by https://hive.ethpandaops.io/#/test/generic/1778481210-e59b7465e1d04f7ed1b0200838584b16?testnumber=137. engine.AssembleBlock explicitly expects withdrawals to be non-nil for pre-Shanghai blocks as opposed to FinaliseAndAssemble which stripped off the withdrawal.
This commit is contained in:
parent
56d391b601
commit
c16684c1ee
2 changed files with 67 additions and 1 deletions
|
|
@ -2680,6 +2680,67 @@ func TestSimulateV1TxSender(t *testing.T) {
|
||||||
require.Equal(t, sender2, summary[1].Transactions[0].From, "sender address mismatch")
|
require.Equal(t, sender2, summary[1].Transactions[0].From, "sender address mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSimulateV1WithdrawalsByFork verifies that withdrawals and withdrawalsRoot
|
||||||
|
// are only emitted in the simulated block result when the simulated block is
|
||||||
|
// post-Shanghai. Pre-Shanghai blocks must omit both fields, otherwise the
|
||||||
|
// header hash and size would not match a valid pre-Shanghai block.
|
||||||
|
func TestSimulateV1WithdrawalsByFork(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
run := func(t *testing.T, cfg *params.ChainConfig, blockTime *uint64, wantWithdrawals bool) {
|
||||||
|
t.Helper()
|
||||||
|
gspec := &core.Genesis{Config: cfg, Alloc: types.GenesisAlloc{}}
|
||||||
|
backend := newTestBackend(t, 1, gspec, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {})
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
stateDB, baseHeader, err := backend.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get state and header: %v", err)
|
||||||
|
}
|
||||||
|
sim := &simulator{
|
||||||
|
b: backend,
|
||||||
|
state: stateDB,
|
||||||
|
base: baseHeader,
|
||||||
|
chainConfig: backend.ChainConfig(),
|
||||||
|
budget: newGasBudget(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
block := simBlock{}
|
||||||
|
if blockTime != nil {
|
||||||
|
t := hexutil.Uint64(*blockTime)
|
||||||
|
block.BlockOverrides = &override.BlockOverrides{Time: &t}
|
||||||
|
}
|
||||||
|
results, err := sim.execute(ctx, []simBlock{block})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("simulation execution failed: %v", err)
|
||||||
|
}
|
||||||
|
require.Len(t, results, 1)
|
||||||
|
|
||||||
|
enc, err := json.Marshal(results[0])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to marshal result: %v", err)
|
||||||
|
}
|
||||||
|
var raw map[string]json.RawMessage
|
||||||
|
if err := json.Unmarshal(enc, &raw); err != nil {
|
||||||
|
t.Fatalf("failed to unmarshal result: %v", err)
|
||||||
|
}
|
||||||
|
_, hasWithdrawals := raw["withdrawals"]
|
||||||
|
_, hasWithdrawalsRoot := raw["withdrawalsRoot"]
|
||||||
|
if hasWithdrawals != wantWithdrawals || hasWithdrawalsRoot != wantWithdrawals {
|
||||||
|
t.Fatalf("unexpected withdrawals fields: withdrawals=%v withdrawalsRoot=%v want=%v\n%s", hasWithdrawals, hasWithdrawalsRoot, wantWithdrawals, enc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("pre-shanghai", func(t *testing.T) {
|
||||||
|
// TestChainConfig has ShanghaiTime=nil, so all simulated blocks are pre-Shanghai.
|
||||||
|
run(t, params.TestChainConfig, nil, false)
|
||||||
|
})
|
||||||
|
t.Run("post-shanghai", func(t *testing.T) {
|
||||||
|
// MergedTestChainConfig has every fork active from genesis.
|
||||||
|
run(t, params.MergedTestChainConfig, nil, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestSignTransaction(t *testing.T) {
|
func TestSignTransaction(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
// Initialize test accounts
|
// Initialize test accounts
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,12 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
|
|
||||||
blockBody := &types.Body{
|
blockBody := &types.Body{
|
||||||
Transactions: txes,
|
Transactions: txes,
|
||||||
Withdrawals: *block.BlockOverrides.Withdrawals, // Withdrawal is also sanitized as non-nil
|
}
|
||||||
|
// Withdrawals are a post-Shanghai field. Attaching a non-nil withdrawals
|
||||||
|
// slice would cause types.NewBlock to populate WithdrawalsHash on the
|
||||||
|
// header and emit withdrawals fields for pre-Shanghai blocks.
|
||||||
|
if sim.chainConfig.IsShanghai(header.Number, header.Time) {
|
||||||
|
blockBody.Withdrawals = *block.BlockOverrides.Withdrawals
|
||||||
}
|
}
|
||||||
chainHeadReader := &simChainHeadReader{ctx, sim.b}
|
chainHeadReader := &simChainHeadReader{ctx, sim.b}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue