From 91e4122aa4ddd92e4ebd0d5114c6b089770bf3bd Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Wed, 15 Apr 2026 15:28:17 +0800 Subject: [PATCH] consensus, core, internal, miner: remove FinalizeAndAssemble --- consensus/beacon/consensus.go | 46 ----------------------------------- consensus/clique/clique.go | 19 --------------- consensus/consensus.go | 9 ------- consensus/ethash/consensus.go | 19 --------------- core/chain_makers.go | 20 +++++++++++---- internal/ethapi/simulate.go | 16 +++++++++--- miner/worker.go | 26 ++++++++++++++++---- 7 files changed, 48 insertions(+), 107 deletions(-) diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index c4a284d485..72ac75c036 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -17,7 +17,6 @@ package beacon import ( - "context" "errors" "fmt" "math/big" @@ -26,13 +25,10 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/internal/telemetry" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" ) @@ -361,48 +357,6 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. // No block reward which is issued by consensus layer instead. } -// FinalizeAndAssemble implements consensus.Engine, setting the final state and -// assembling the block. -func (beacon *Beacon) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body, receipts []*types.Receipt) (result *types.Block, err error) { - ctx, _, spanEnd := telemetry.StartSpan(ctx, "consensus.beacon.FinalizeAndAssemble", - telemetry.Int64Attribute("block.number", int64(header.Number.Uint64())), - telemetry.Int64Attribute("txs.count", int64(len(body.Transactions))), - telemetry.Int64Attribute("withdrawals.count", int64(len(body.Withdrawals))), - ) - defer spanEnd(&err) - - if !beacon.IsPoSHeader(header) { - block, delegateErr := beacon.ethone.FinalizeAndAssemble(ctx, chain, header, state, body, receipts) - return block, delegateErr - } - shanghai := chain.Config().IsShanghai(header.Number, header.Time) - if shanghai { - // All blocks after Shanghai must include a withdrawals root. - if body.Withdrawals == nil { - body.Withdrawals = make([]*types.Withdrawal, 0) - } - } else { - if len(body.Withdrawals) > 0 { - return nil, errors.New("withdrawals set before Shanghai activation") - } - } - // Finalize and assemble the block. - _, _, finalizeSpanEnd := telemetry.StartSpan(ctx, "consensus.beacon.Finalize") - beacon.Finalize(chain, header, state, body) - finalizeSpanEnd(nil) - - // Assign the final state root to header. - _, _, rootSpanEnd := telemetry.StartSpan(ctx, "consensus.beacon.IntermediateRoot") - header.Root = state.IntermediateRoot(true) - rootSpanEnd(nil) - - // Assemble the final block. - _, _, blockSpanEnd := telemetry.StartSpan(ctx, "consensus.beacon.NewBlock") - block := types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)) - blockSpanEnd(nil) - return block, nil -} - // Seal generates a new sealing request for the given input block and pushes // the result into the given channel. // diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 3bf79d5a62..ceaec44656 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -19,7 +19,6 @@ package clique import ( "bytes" - "context" "errors" "fmt" "io" @@ -34,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -43,7 +41,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" ) const ( @@ -580,22 +577,6 @@ func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Heade // No block rewards in PoA, so the state remains as is } -// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, -// nor block rewards given, and returns the final block. -func (c *Clique) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body, receipts []*types.Receipt) (*types.Block, error) { - if len(body.Withdrawals) > 0 { - return nil, errors.New("clique does not support withdrawals") - } - // Finalize block - c.Finalize(chain, header, state, body) - - // Assign the final state root to header. - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) - - // Assemble and return the final block for sealing. - return types.NewBlock(header, &types.Body{Transactions: body.Transactions}, receipts, trie.NewStackTrie(nil)), nil -} - // Authorize injects a private key into the consensus engine to mint new blocks // with. func (c *Clique) Authorize(signer common.Address) { diff --git a/consensus/consensus.go b/consensus/consensus.go index 094026b614..4ba389292f 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -18,11 +18,9 @@ package consensus import ( - "context" "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" @@ -88,13 +86,6 @@ type Engine interface { // that happen at finalization (e.g. block rewards). Finalize(chain ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body) - // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block - // rewards or process withdrawals) and assembles the final block. - // - // Note: The block header and state database might be updated to reflect any - // consensus rules that happen at finalization (e.g. block rewards). - FinalizeAndAssemble(ctx context.Context, chain ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body, receipts []*types.Receipt) (*types.Block, error) - // Seal generates a new sealing request for the given input block and pushes // the result into the given channel. // diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 56256d1215..ee9d9d97d6 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -17,7 +17,6 @@ package ethash import ( - "context" "errors" "fmt" "math/big" @@ -28,14 +27,12 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto/keccak" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" ) @@ -512,22 +509,6 @@ func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types. accumulateRewards(chain.Config(), state, header, body.Uncles) } -// FinalizeAndAssemble implements consensus.Engine, accumulating the block and -// uncle rewards, setting the final state and assembling the block. -func (ethash *Ethash) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body, receipts []*types.Receipt) (*types.Block, error) { - if len(body.Withdrawals) > 0 { - return nil, errors.New("ethash does not support withdrawals") - } - // Finalize block - ethash.Finalize(chain, header, state, body) - - // Assign the final state root to header. - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) - - // Header seems complete, assemble into a block and return - return types.NewBlock(header, &types.Body{Transactions: body.Transactions, Uncles: body.Uncles}, receipts, trie.NewStackTrie(nil)), nil -} - // SealHash returns the hash of a block prior to it being sealed. func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { hasher := keccak.NewLegacyKeccak256() diff --git a/core/chain_makers.go b/core/chain_makers.go index 3bc7f6528b..0ea272bc60 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -17,7 +17,6 @@ package core import ( - "context" "fmt" "math/big" @@ -32,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" ) @@ -411,12 +411,22 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse b.header.RequestsHash = &reqHash } - body := types.Body{Transactions: b.txs, Uncles: b.uncles, Withdrawals: b.withdrawals} - block, err := b.engine.FinalizeAndAssemble(context.Background(), cm, b.header, statedb, &body, b.receipts) - if err != nil { - panic(err) + body := types.Body{ + Transactions: b.txs, + Uncles: b.uncles, + Withdrawals: b.withdrawals, } + // Finalize the state transition by applying operations such as withdrawals, + // uncle rewards, and related processing. + b.engine.Finalize(cm, b.header, statedb, &body) + + // Calculate the state root after applying all mutations. + b.header.Root = statedb.IntermediateRoot(cm.Config().IsEIP158(b.header.Number)) + + // Assemble the block for delivery. + block := types.NewBlock(b.header, &body, b.receipts, trie.NewStackTrie(nil)) + // Write state changes to db root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time)) if err != nil { diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 90e88e83ee..4fe690030d 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -37,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/internal/ethapi/override" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/trie" ) const ( @@ -419,10 +420,17 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, Withdrawals: *block.BlockOverrides.Withdrawals, } chainHeadReader := &simChainHeadReader{ctx, sim.b} - b, err := sim.b.Engine().FinalizeAndAssemble(ctx, chainHeadReader, header, sim.state, blockBody, receipts) - if err != nil { - return nil, nil, nil, err - } + + // Finalize the state transition by applying operations such as withdrawals, + // uncle rewards, and related processing. + sim.b.Engine().Finalize(chainHeadReader, header, sim.state, blockBody) + + // Calculate the state root after applying all mutations. + header.Root = sim.state.IntermediateRoot(chainHeadReader.Config().IsEIP158(header.Number)) + + // Assemble the block for delivery. + b := types.NewBlock(header, blockBody, receipts, trie.NewStackTrie(nil)) + repairLogs(callResults, b.Hash()) return b, callResults, senders, nil } diff --git a/miner/worker.go b/miner/worker.go index 1d648f0ee1..f35406198c 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/internal/telemetry" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" ) @@ -183,7 +184,17 @@ func (miner *Miner) generateWork(ctx context.Context, genParam *generateParams, } } } - body := types.Body{Transactions: work.txs, Withdrawals: genParam.withdrawals} + // Construct the block body, the withdrawal list should never be null + // if Shanghai has been activated. + body := types.Body{ + Transactions: work.txs, + Withdrawals: genParam.withdrawals, + } + if miner.chainConfig.IsShanghai(work.header.Number, work.header.Time) { + if body.Withdrawals == nil { + body.Withdrawals = make([]*types.Withdrawal, 0) + } + } allLogs := make([]*types.Log, 0) for _, r := range work.receipts { @@ -211,11 +222,16 @@ func (miner *Miner) generateWork(ctx context.Context, genParam *generateParams, reqHash := types.CalcRequestsHash(requests) work.header.RequestsHash = &reqHash } + // Finalize the state transition by applying operations such as withdrawals, + // uncle rewards, and related processing. + miner.engine.Finalize(miner.chain, work.header, work.state, &body) + + // Calculate the state root after applying all mutations. + work.header.Root = work.state.IntermediateRoot(miner.chain.Config().IsEIP158(work.header.Number)) + + // Assemble the block for delivery. + block := types.NewBlock(work.header, &body, work.receipts, trie.NewStackTrie(nil)) - block, err := miner.engine.FinalizeAndAssemble(ctx, miner.chain, work.header, work.state, &body, work.receipts) - if err != nil { - return &newPayloadResult{err: err} - } return &newPayloadResult{ block: block, fees: totalFees(block, work.receipts),