diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 20067baf39..0e49bc65d2 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -651,11 +651,11 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H if header.RequestsHash != nil { 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") - // } + } else { + if !header.EmptyRequestsHash() { + log.Info("verifyHeader", "header.EmptyRequestsHash", header.EmptyRequestsHash()) + return errors.New("header has wrong RequestsHash") + } } // All basic checks passed, verify cascading fields diff --git a/core/chain_makers.go b/core/chain_makers.go index 1d33aef4c2..7b9b18bc87 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -371,7 +371,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse } var requests [][]byte - if config.IsPrague(b.header.Number, b.header.Time) { + isPrague := config.IsPrague(b.header.Number, b.header.Time) + if isPrague && config.Parlia == nil { // EIP-6110 deposits var blockLogs []*types.Log for _, r := range b.receipts { @@ -391,6 +392,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse // EIP-7251 consolidations consolidationRequests := ProcessConsolidationQueue(vmenv, statedb) requests = append(requests, consolidationRequests) + } else if isPrague && config.Parlia != nil { + requests = make([][]byte, 0) } if requests != nil { reqHash := types.CalcRequestsHash(requests) @@ -612,11 +615,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 4a45d12942..9b3ef1ec9d 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -480,9 +480,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/state_processor.go b/core/state_processor.go index c7f4f39917..ba62e347e0 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -149,7 +149,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // Read requests if Prague is enabled. var requests [][]byte - if p.config.IsPrague(block.Number(), block.Time()) { + isPrague := p.config.IsPrague(block.Number(), block.Time()) + if isPrague && p.chain.config.Parlia == nil { var allCommonLogs []*types.Log for _, receipt := range receipts { allCommonLogs = append(allCommonLogs, receipt.Logs...) @@ -165,6 +166,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // EIP-7251 consolidations consolidationRequests := ProcessConsolidationQueue(vmenv, tracingStateDB) requests = append(requests, consolidationRequests) + } else if isPrague && p.chain.config.Parlia != nil { + requests = make([][]byte, 0) } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) diff --git a/core/types/block.go b/core/types/block.go index d56c985994..554bcc41e3 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -211,6 +211,11 @@ func (h *Header) EmptyWithdrawalsHash() bool { return h.WithdrawalsHash != nil && *h.WithdrawalsHash == EmptyWithdrawalsHash } +// EmptyRequestsHash returns true if the RequestsHash is EmptyRequestsHash. +func (h *Header) EmptyRequestsHash() bool { + return h.RequestsHash != nil && *h.RequestsHash == EmptyRequestsHash +} + // Body is a simple (mutable, non-safe) data container for storing and moving // a block's data contents (transactions and uncles) together. type Body struct { @@ -509,9 +514,11 @@ func CalcRequestsHash(requests [][]byte) common.Hash { h1, h2 := sha256.New(), sha256.New() var buf common.Hash for _, item := range requests { - h1.Reset() - h1.Write(item) - h2.Write(h1.Sum(buf[:0])) + if len(item) > 1 { // skip items with only requestType and no data. + h1.Reset() + h1.Write(item) + h2.Write(h1.Sum(buf[:0])) + } } h2.Sum(buf[:0]) return buf diff --git a/core/types/hashes.go b/core/types/hashes.go index 43e9130fd1..f9a37f12c3 100644 --- a/core/types/hashes.go +++ b/core/types/hashes.go @@ -41,6 +41,9 @@ var ( // EmptyWithdrawalsHash is the known hash of the empty withdrawal set. EmptyWithdrawalsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + // EmptyRequestsHash is the known hash of the empty requests set. + EmptyRequestsHash = common.HexToHash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + // EmptyVerkleHash is the known hash of an empty verkle trie. EmptyVerkleHash = common.Hash{} ) diff --git a/miner/worker.go b/miner/worker.go index 972662c298..11cf653bc6 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1025,13 +1025,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.