Skip to content

Commit

Permalink
Protection against duplicate requests to build the same block (erigon…
Browse files Browse the repository at this point in the history
…tech#5795)

If I'm not mistaken, some CLs in some circumstances can send duplicate
requests to build a block. This is a protection against throwing away
progress in case block building has already started.
  • Loading branch information
yperbasis authored and finiteops committed Apr 10, 2023
1 parent 653e05f commit 909a9dc
Showing 1 changed file with 24 additions and 11 deletions.
35 changes: 24 additions & 11 deletions ethdb/privateapi/ethbackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"math/big"
"reflect"
"sync"
"time"

Expand Down Expand Up @@ -60,15 +61,17 @@ type EthBackendServer struct {
db kv.RoDB
blockReader services.BlockAndTxnReader
config *chain.Config

// Block proposing for proof-of-stake
payloadId uint64
builders map[uint64]*builder.BlockBuilder

builderFunc builder.BlockBuilderFunc
proposing bool
lock sync.Mutex // Engine API is asynchronous, we want to avoid CL to call different APIs at the same time
logsFilter *LogsFilterAggregator
hd *headerdownload.HeaderDownload
payloadId uint64
lastParameters *core.BlockBuilderParameters
builders map[uint64]*builder.BlockBuilder
builderFunc builder.BlockBuilderFunc
proposing bool

lock sync.Mutex // Engine API is asynchronous, we want to avoid CL to call different APIs at the same time
logsFilter *LogsFilterAggregator
hd *headerdownload.HeaderDownload
}

type EthBackend interface {
Expand Down Expand Up @@ -671,17 +674,27 @@ func (s *EthBackendServer) EngineForkChoiceUpdated(ctx context.Context, req *rem
if payloadAttributes.Version >= 2 {
param.Withdrawals = ConvertWithdrawalsFromRpc(payloadAttributes.Withdrawals)
}

if err := s.checkWithdrawalsPresence(payloadAttributes.Timestamp, param.Withdrawals); err != nil {
return nil, err
}

// Initiate payload building
// First check if we're already building a block with the requested parameters
if reflect.DeepEqual(s.lastParameters, &param) {
return &remote.EngineForkChoiceUpdatedResponse{
PayloadStatus: &remote.EnginePayloadStatus{
Status: remote.EngineStatus_VALID,
LatestValidHash: gointerfaces.ConvertHashToH256(headHash),
},
PayloadId: s.payloadId,
}, nil
}

// Initiate payload building
s.evictOldBuilders()

// payload IDs start from 1 (0 signifies null)
s.payloadId++
param.PayloadId = s.payloadId
s.lastParameters = &param

s.builders[s.payloadId] = builder.NewBlockBuilder(s.builderFunc, &param)
log.Debug("BlockBuilder added", "payload", s.payloadId)
Expand Down

0 comments on commit 909a9dc

Please sign in to comment.