Skip to content

Commit

Permalink
Update Empty requests list behaviour for Pectra-5 (#12985)
Browse files Browse the repository at this point in the history
The updated EIP-7685 says requests with empty `request_data` should be
dropped from `executionRequests` field in the API and ignored for hash
calculation.
See ethereum/EIPs#8989,
ethereum/execution-apis#599

Issue board: #12401
  • Loading branch information
somnathb1 committed Jan 15, 2025
1 parent 8288f26 commit 30f9453
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 61 deletions.
20 changes: 13 additions & 7 deletions consensus/merge/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat

var rs types.FlatRequests
if config.IsPrague(header.Time) {
rs = make(types.FlatRequests, len(types.KnownRequestTypes))
rs = make(types.FlatRequests, 0)
allLogs := make(types.Logs, 0)
for _, rec := range receipts {
allLogs = append(allLogs, rec.Logs...)
Expand All @@ -171,11 +171,17 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat
if err != nil {
return nil, nil, nil, fmt.Errorf("error: could not parse requests logs: %v", err)
}
rs[0] = *depositReqs
if depositReqs != nil {
rs = append(rs, *depositReqs)
}
withdrawalReq := misc.DequeueWithdrawalRequests7002(syscall)
rs[1] = *withdrawalReq
if withdrawalReq != nil {
rs = append(rs, *withdrawalReq)
}
consolidations := misc.DequeueConsolidationRequests7251(syscall)
rs[2] = *consolidations
if consolidations != nil {
rs = append(rs, *consolidations)
}
if header.RequestsHash != nil {
rh := rs.Hash()
if *header.RequestsHash != *rh {
Expand All @@ -194,15 +200,15 @@ func (s *Merge) FinalizeAndAssemble(config *chain.Config, header *types.Header,
return s.eth1Engine.FinalizeAndAssemble(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall, call, logger)
}
header.RequestsHash = nil
outTxs, outReceipts, rs, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall, logger)
outTxs, outReceipts, outRequests, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall, logger)

if err != nil {
return nil, nil, nil, nil, err
}
if config.IsPrague(header.Time) {
header.RequestsHash = rs.Hash()
header.RequestsHash = outRequests.Hash()
}
return types.NewBlockForAsembling(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, rs, nil
return types.NewBlockForAsembling(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, outRequests, nil
}

func (s *Merge) SealHash(header *types.Header) (hash libcommon.Hash) {
Expand Down
5 changes: 4 additions & 1 deletion consensus/misc/eip6110.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,8 @@ func ParseDepositLogs(logs []*types.Log, depositContractAddress libcommon.Addres
reqData = append(reqData, d...)
}
}
return &types.FlatRequest{Type: types.DepositRequestType, RequestData: reqData}, nil
if len(reqData) > 0 {
return &types.FlatRequest{Type: types.DepositRequestType, RequestData: reqData}, nil
}
return nil, nil
}
8 changes: 4 additions & 4 deletions consensus/misc/eip7002.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ func DequeueWithdrawalRequests7002(syscall consensus.SystemCall) *types.FlatRequ
log.Warn("Err with syscall to WithdrawalRequestAddress", "err", err)
return nil
}
if res == nil {
res = make([]byte, 0)
if res != nil {
// Just append the contract output
return &types.FlatRequest{Type: types.WithdrawalRequestType, RequestData: res}
}
// Just append the contract outputs
return &types.FlatRequest{Type: types.WithdrawalRequestType, RequestData: res}
return nil
}
8 changes: 4 additions & 4 deletions consensus/misc/eip7251.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ func DequeueConsolidationRequests7251(syscall consensus.SystemCall) *types.FlatR
log.Warn("Err with syscall to ConsolidationRequestAddress", "err", err)
return nil
}
if res == nil {
res = make([]byte, 0)
if res != nil {
// Just append the contract output as the request data
return &types.FlatRequest{Type: types.ConsolidationRequestType, RequestData: res}
}
// Just append the contract outputs as the encoded request data
return &types.FlatRequest{Type: types.ConsolidationRequestType, RequestData: res}
return nil
}
1 change: 0 additions & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ func FinalizeBlockExecution(
if isMining {
newBlock, newTxs, newReceipt, retRequests, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, withdrawals, chainReader, syscall, nil, logger)
} else {
// var rss types.Requests
newTxs, newReceipt, retRequests, err = engine.Finalize(cc, header, ibs, txs, uncles, receipts, withdrawals, chainReader, syscall, logger)
}
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import (

var (
EmptyRootHash = libcommon.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
EmptyRequestsHash = libcommon.HexToHash("6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f")
EmptyRequestsHash = libcommon.HexToHash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") // sha256.Sum256([]byte(""))
EmptyUncleHash = rlpHash([]*Header(nil))

ExtraVanityLength = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
Expand Down
6 changes: 3 additions & 3 deletions core/types/eip7685_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ func (f *FlatRequest) copy() *FlatRequest {
type FlatRequests []FlatRequest

func (r FlatRequests) Hash() *libcommon.Hash {
if r == nil || len(r) < len(KnownRequestTypes) {
if r == nil {
return nil
}
sha := sha256.New()
for i, t := range KnownRequestTypes {
hi := sha256.Sum256(append([]byte{t}, r[i].RequestData...))
for i, t := range r {
hi := sha256.Sum256(append([]byte{t.Type}, r[i].RequestData...))
sha.Write(hi[:])
}
h := libcommon.BytesToHash(sha.Sum(nil))
Expand Down
30 changes: 30 additions & 0 deletions core/types/requests_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2025 The Erigon Authors
// This file is part of Erigon.
//
// Erigon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Erigon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Erigon. If not, see <http://www.gnu.org/licenses/>.

package types

import (
"testing"
)

func TestEmptyRequestsHashCalculation(t *testing.T) {
reqs := make(FlatRequests, 0)
h := reqs.Hash()
testH := EmptyRequestsHash
if *h != testH {
t.Errorf("Requests Hash calculation error for empty hash, expected: %v, got: %v", testH, h)
}
}
7 changes: 1 addition & 6 deletions turbo/builder/block_builder.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package builder

import (
"fmt"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -34,11 +33,7 @@ func NewBlockBuilder(build BlockBuilderFunc, param *core.BlockBuilderParameters)
log.Warn("Failed to build a block", "err", err)
} else {
block := result.Block
reqLenStr := "nil"
if len(result.Requests) == 3 {
reqLenStr = fmt.Sprint("Deposit Requests", len(result.Requests[0].RequestData), "Withdrawal Requests", len(result.Requests[1].RequestData), "Consolidation Requests", len(result.Requests[2].RequestData))
}
log.Info("Built block", "hash", block.Hash(), "height", block.NumberU64(), "txs", len(block.Transactions()), "executionRequests", len(result.Requests), "Requests", reqLenStr, "gas used %", 100*float64(block.GasUsed())/float64(block.GasLimit()), "time", time.Since(t))
log.Info("Built block", "hash", block.Hash(), "height", block.NumberU64(), "txs", len(block.Transactions()), "executionRequests", len(result.Requests), "gas used %", 100*float64(block.GasUsed())/float64(block.GasLimit()), "time", time.Since(t))
}

builder.syncCond.L.Lock()
Expand Down
28 changes: 8 additions & 20 deletions turbo/engineapi/engine_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,6 @@ func (s *EngineServer) checkRequestsPresence(time uint64, executionRequests []he
return &rpc.InvalidParamsError{Message: "requests before Prague"}
}
}
// if s.config.IsPrague(time) {
// if len(executionRequests) < 3 {
// return &rpc.InvalidParamsError{Message: "missing requests list"}
// }
// }
return nil
}

Expand Down Expand Up @@ -182,12 +177,12 @@ func (s *EngineServer) newPayload(ctx context.Context, req *engine_types.Executi
return nil, err
}
if version >= clparams.ElectraVersion {
requests = make(types.FlatRequests, len(types.KnownRequestTypes))
for i, r := range types.KnownRequestTypes {
if len(executionRequests) == i {
executionRequests = append(executionRequests, []byte{})
requests = make(types.FlatRequests, 0)
for i, r := range executionRequests {
if len(r) <= 1 {
return nil, &rpc.InvalidParamsError{Message: fmt.Sprintf("Invalid Request at index %d", i)}
}
requests[i] = types.FlatRequest{Type: r, RequestData: executionRequests[i]}
requests = append(requests, types.FlatRequest{Type: r[0], RequestData: r})
}
rh := requests.Hash()
header.RequestsHash = rh
Expand Down Expand Up @@ -460,16 +455,9 @@ func (s *EngineServer) getPayload(ctx context.Context, payloadId uint64, version
data := resp.Data
var executionRequests []hexutility.Bytes
if version >= clparams.ElectraVersion {
executionRequests = make([]hexutility.Bytes, len(types.KnownRequestTypes))
if len(data.Requests.Requests) != 3 {
s.logger.Warn("Error in getPayload - data.Requests.Requests len not 3")
}
for i := 0; i < len(types.KnownRequestTypes); i++ {
if len(data.Requests.Requests) < i+1 || data.Requests.Requests[i] == nil {
executionRequests[i] = make(hexutility.Bytes, 0)
} else {
executionRequests[i] = data.Requests.Requests[i]
}
executionRequests = make([]hexutility.Bytes, 0)
for _, r := range data.Requests.Requests {
executionRequests = append(executionRequests, r)
}
}

Expand Down
22 changes: 8 additions & 14 deletions turbo/execution/eth1/block_building.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,29 +199,23 @@ func (e *EthereumExecutionModule) GetAssembledBlock(ctx context.Context, req *ex
}
}

var requestsBundle types2.RequestsBundle
var requestsBundle *types2.RequestsBundle
if blockWithReceipts.Requests != nil {
requests := make([][]byte, len(types.KnownRequestTypes))
if len(blockWithReceipts.Requests) == len(types.KnownRequestTypes) {
for i, r := range blockWithReceipts.Requests {
requests[i] = make([]byte, 0)
requests[i] = append(requests[i], r.RequestData...)
}
} else {
e.logger.Error("Requests len SHOULD BE", "equal to", len(types.KnownRequestTypes), "got", len(blockWithReceipts.Requests))
for i := 0; i < len(types.KnownRequestTypes); i++ {
requests[i] = make([]byte, 0)
}
requestsBundle = &types2.RequestsBundle{}
requests := make([][]byte, 0)
for i, r := range blockWithReceipts.Requests {
requests[i] = make([]byte, 0)
requests[i] = append(requests[i], r.RequestData...)
}
requestsBundle = types2.RequestsBundle{Requests: requests}
requestsBundle.Requests = requests
}

return &execution.GetAssembledBlockResponse{
Data: &execution.AssembledBlockData{
ExecutionPayload: payload,
BlockValue: gointerfaces.ConvertUint256IntToH256(blockValue),
BlobsBundle: blobsBundle,
Requests: &requestsBundle,
Requests: requestsBundle,
},
Busy: false,
}, nil
Expand Down

0 comments on commit 30f9453

Please sign in to comment.