diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 176c742b9a..7a5219fd3b 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -652,7 +652,6 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H return fmt.Errorf("invalid RequestsHash, have %#x, expected nil", header.ParentBeaconRoot) } } else { - // TODO(Nathan): need a BEP to define this and `Requests` in struct Body if !header.EmptyRequestsHash() { return errors.New("header has wrong RequestsHash") } diff --git a/core/chain_makers.go b/core/chain_makers.go index 27bf4e02b3..a1889be3d6 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -51,6 +51,7 @@ type BlockGen struct { receipts []*types.Receipt uncles []*types.Header withdrawals []*types.Withdrawal + requests []*types.Request engine consensus.Engine @@ -337,6 +338,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse if b.header.EmptyWithdrawalsHash() { b.withdrawals = make([]*types.Withdrawal, 0) } + if b.header.EmptyRequestsHash() { + b.requests = make([]*types.Request, 0) + } // Set the difficulty for clique block. The chain maker doesn't have access // to a chain, so the difficulty will be left unset (nil). Set it here to the @@ -601,11 +605,16 @@ func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engi excessBlobGas := eip4844.CalcExcessBlobGas(parentExcessBlobGas, parentBlobGasUsed) header.ExcessBlobGas = &excessBlobGas header.BlobGasUsed = new(uint64) - if cm.config.Parlia != nil { - header.WithdrawalsHash = &types.EmptyWithdrawalsHash - } - if cm.config.Parlia == nil || cm.config.IsBohr(header.Number, header.Time) { + if cm.config.Parlia == nil { header.ParentBeaconRoot = new(common.Hash) + } else { + header.WithdrawalsHash = &types.EmptyWithdrawalsHash + if cm.config.IsBohr(header.Number, header.Time) { + header.ParentBeaconRoot = new(common.Hash) + if cm.config.IsPrague(header.Number, header.Time) { + header.RequestsHash = &types.EmptyRequestsHash + } + } } } return header diff --git a/core/genesis.go b/core/genesis.go index 6f8ea436fa..a8fe54e3bb 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -481,9 +481,11 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { ) if conf := g.Config; conf != nil { num := big.NewInt(int64(g.Number)) - if conf.Parlia == nil && conf.IsShanghai(num, g.Timestamp) { - head.WithdrawalsHash = &types.EmptyWithdrawalsHash - withdrawals = make([]*types.Withdrawal, 0) + if conf.IsShanghai(num, g.Timestamp) { + if conf.Parlia == nil { + head.WithdrawalsHash = &types.EmptyWithdrawalsHash + withdrawals = make([]*types.Withdrawal, 0) + } } if conf.IsCancun(num, g.Timestamp) { if conf.Parlia != nil { diff --git a/core/types/block.go b/core/types/block.go index b143ee61cc..60bb862c70 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -586,6 +586,23 @@ func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block { return block } +// WithRequests returns a copy of the block containing the given requests. +func (b *Block) WithRequests(requests []*Request) *Block { + block := &Block{ + header: b.header, + transactions: b.transactions, + uncles: b.uncles, + withdrawals: b.withdrawals, + witness: b.witness, + sidecars: b.sidecars, + } + if requests != nil { + block.requests = make([]*Request, len(requests)) + copy(block.requests, requests) + } + return block +} + // WithSidecars returns a block containing the given blobs. func (b *Block) WithSidecars(sidecars BlobSidecars) *Block { block := &Block{ diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index e708cdfb0e..3f7e71acb6 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -1355,6 +1355,9 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error { blocks := make([]*types.Block, len(results)) for i, result := range results { blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.body()).WithSidecars(result.Sidecars) + if blocks[i].Header().EmptyRequestsHash() { + blocks[i] = blocks[i].WithRequests(make([]*types.Request, 0)) + } } // Downloaded blocks are always regarded as trusted after the // transition. Because the downloaded chain is guided by the diff --git a/eth/fetcher/block_fetcher.go b/eth/fetcher/block_fetcher.go index c5694f7f51..38b625bf0a 100644 --- a/eth/fetcher/block_fetcher.go +++ b/eth/fetcher/block_fetcher.go @@ -644,6 +644,9 @@ func (f *BlockFetcher) loop() { if block.Header().EmptyWithdrawalsHash() { block = block.WithWithdrawals(make([]*types.Withdrawal, 0)) } + if block.Header().EmptyRequestsHash() { + block = block.WithRequests(make([]*types.Request, 0)) + } block.ReceivedAt = task.time complete = append(complete, block) @@ -916,6 +919,9 @@ func (f *BlockFetcher) importBlocks(op *blockOrHeaderInject) { if block.Header().EmptyWithdrawalsHash() { block = block.WithWithdrawals(make([]*types.Withdrawal, 0)) } + if block.Header().EmptyRequestsHash() { + block = block.WithRequests(make([]*types.Request, 0)) + } defer func() { f.done <- hash }() // Quickly validate the header and propagate the block if it passes diff --git a/eth/handler.go b/eth/handler.go index 8e763dfb8b..ba2fe442aa 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -279,11 +279,14 @@ func newHandler(config *handlerConfig) (*handler, error) { broadcastBlockWithCheck := func(block *types.Block, propagate bool) { if propagate { - if !(block.Header().WithdrawalsHash == nil && block.Withdrawals() == nil) && - !(block.Header().EmptyWithdrawalsHash() && block.Withdrawals() != nil && len(block.Withdrawals()) == 0) { + if block.Header().WithdrawalsHash == nil && block.Withdrawals() != nil { log.Error("Propagated block has invalid withdrawals") return } + if block.Header().RequestsHash == nil && block.Requests() != nil { + log.Error("Propagated block has invalid requests") + return + } if err := core.IsDataAvailable(h.chain, block); err != nil { log.Error("Propagating block with invalid sidecars", "number", block.Number(), "hash", block.Hash(), "err", err) return diff --git a/miner/worker.go b/miner/worker.go index d193ccca3c..b3e0674ca6 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -707,6 +707,9 @@ func (w *worker) updateSnapshot(env *environment) { if env.header.EmptyWithdrawalsHash() { body.Withdrawals = make([]*types.Withdrawal, 0) } + if env.header.EmptyRequestsHash() { + body.Requests = make([]*types.Request, 0) + } w.snapshotBlock = types.NewBlock( env.header, &body, @@ -1024,13 +1027,16 @@ func (w *worker) prepareWork(genParams *generateParams, witness bool) (*environm } header.BlobGasUsed = new(uint64) header.ExcessBlobGas = &excessBlobGas - if w.chainConfig.Parlia != nil { - header.WithdrawalsHash = &types.EmptyWithdrawalsHash - } if w.chainConfig.Parlia == nil { header.ParentBeaconRoot = genParams.beaconRoot - } else if w.chainConfig.IsBohr(header.Number, header.Time) { - header.ParentBeaconRoot = new(common.Hash) + } else { + header.WithdrawalsHash = &types.EmptyWithdrawalsHash + if w.chainConfig.IsBohr(header.Number, header.Time) { + header.ParentBeaconRoot = new(common.Hash) + if w.chainConfig.IsPrague(header.Number, header.Time) { + header.RequestsHash = &types.EmptyRequestsHash + } + } } } // Could potentially happen if starting to mine in an odd state. @@ -1429,6 +1435,9 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti if env.header.EmptyWithdrawalsHash() { body.Withdrawals = make([]*types.Withdrawal, 0) } + if env.header.EmptyRequestsHash() { + body.Requests = make([]*types.Request, 0) + } block, receipts, err := w.engine.FinalizeAndAssemble(w.chain, types.CopyHeader(env.header), env.state, &body, env.receipts) if err != nil { return err