Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Empty requests list behaviour for Pectra-5 #12985

Merged
merged 10 commits into from
Jan 14, 2025
20 changes: 13 additions & 7 deletions consensus/merge/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,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 @@ -196,11 +196,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 @@ -219,15 +225,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
}
6 changes: 3 additions & 3 deletions consensus/misc/eip7002.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,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 {
return &types.FlatRequest{Type: types.WithdrawalRequestType, RequestData: res}
}
return nil
// Just append the contract outputs
somnathb1 marked this conversation as resolved.
Show resolved Hide resolved
return &types.FlatRequest{Type: types.WithdrawalRequestType, RequestData: res}
}
6 changes: 3 additions & 3 deletions consensus/misc/eip7251.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,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 {
return &types.FlatRequest{Type: types.ConsolidationRequestType, RequestData: res}
}
return nil
// Just append the contract outputs as the encoded request data
somnathb1 marked this conversation as resolved.
Show resolved Hide resolved
return &types.FlatRequest{Type: types.ConsolidationRequestType, RequestData: res}
}
1 change: 0 additions & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,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
somnathb1 marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -40,7 +40,7 @@ import (

var (
EmptyRootHash = libcommon.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
EmptyRequestsHash = libcommon.HexToHash("6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f")
EmptyRequestsHash = libcommon.HexToHash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
somnathb1 marked this conversation as resolved.
Show resolved Hide resolved
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
37 changes: 37 additions & 0 deletions core/types/reqeusts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2014 The go-ethereum Authors
somnathb1 marked this conversation as resolved.
Show resolved Hide resolved
// (original work)
// Copyright 2024 The Erigon Authors
// (modifications)
// 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 (
"crypto/sha256"
"testing"

libcommon "github.com/erigontech/erigon-lib/common"
)

func TestEmptyRequestsHashCalculation(t *testing.T) {
somnathb1 marked this conversation as resolved.
Show resolved Hide resolved
reqs := make(FlatRequests, 0)
h := reqs.Hash()
testHArr := sha256.Sum256([]byte(""))
testH := libcommon.BytesToHash(testHArr[:])
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
Expand Up @@ -17,7 +17,6 @@
package builder

import (
"fmt"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -50,11 +49,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
29 changes: 6 additions & 23 deletions turbo/engineapi/engine_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,6 @@ func (s *EngineServer) checkRequestsPresence(version clparams.StateVersion, exec
if executionRequests != nil {
return &rpc.InvalidParamsError{Message: "requests in EngineAPI not supported before Prague"}
}
} else {
if executionRequests == nil {
return &rpc.InvalidParamsError{Message: "missing requests list"}
}
if len(executionRequests) != len(types.KnownRequestTypes) {
return &rpc.InvalidParamsError{Message: "invalid requests lists"}
}
}
return nil
}
Expand Down Expand Up @@ -215,12 +208,9 @@ 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[i] = types.FlatRequest{Type: r, RequestData: executionRequests[i]}
requests = make(types.FlatRequests, 0)
for _, r := range executionRequests {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please guard against the case when r is empty

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this bit of the spec implemented: "Elements of the list MUST be ordered by request_type in ascending order. Elements with empty request_data MUST be excluded from the list. If any element is out of order or has a length of 1-byte or shorter, client software MUST return -32602: Invalid params error."?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, here it doesn't throw the error. This was beneficial to run some early implementations of CLs, but I have made the change now to address the concern.

requests = append(requests, types.FlatRequest{Type: r[0], RequestData: r})
}
rh := requests.Hash()
header.RequestsHash = rh
Expand Down Expand Up @@ -499,16 +489,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 @@ -215,29 +215,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
Loading