-
Notifications
You must be signed in to change notification settings - Fork 198
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
chore(block-builder): a few minor cleanups #2412
Changes from 7 commits
4c4cc0f
eb87f0b
6b9ea26
3709ccb
a2df05f
0d3ceb7
44be9ac
c21abb2
44ea391
6d8e8e9
ef8963e
99c7ce3
6b1866b
92ce082
6df1a28
d566a6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,8 +28,8 @@ import ( | |
payloadtime "github.com/berachain/beacon-kit/beacon/payload-time" | ||
ctypes "github.com/berachain/beacon-kit/consensus-types/types" | ||
"github.com/berachain/beacon-kit/consensus/types" | ||
datypes "github.com/berachain/beacon-kit/da/types" | ||
"github.com/berachain/beacon-kit/errors" | ||
"github.com/berachain/beacon-kit/payload/builder" | ||
"github.com/berachain/beacon-kit/primitives/bytes" | ||
"github.com/berachain/beacon-kit/primitives/common" | ||
"github.com/berachain/beacon-kit/primitives/crypto" | ||
|
@@ -41,21 +41,19 @@ import ( | |
|
||
// BuildBlockAndSidecars builds a new beacon block. | ||
// | ||
//nolint:funlen | ||
|
||
func (s *Service) BuildBlockAndSidecars( | ||
ctx context.Context, | ||
slotData *types.SlotData, | ||
) ([]byte, []byte, error) { | ||
var ( | ||
signedBlk *ctypes.SignedBeaconBlock | ||
blk *ctypes.BeaconBlock | ||
sidecars datypes.BlobSidecars | ||
forkData *ctypes.ForkData | ||
) | ||
|
||
startTime := time.Now() | ||
defer s.metrics.measureRequestBlockForProposalTime(startTime) | ||
|
||
if !s.localPayloadBuilder.Enabled() { | ||
// node is not supposed to build blocks | ||
return nil, nil, builder.ErrPayloadBuilderDisabled | ||
} | ||
|
||
// The goal here is to acquire a payload whose parent is the previously | ||
// finalized block, such that, if this payload is accepted, it will be | ||
// the next finalized block in the chain. A byproduct of this design | ||
|
@@ -85,7 +83,7 @@ func (s *Service) BuildBlockAndSidecars( | |
} | ||
|
||
// Create a new empty block from the current state. | ||
blk, err = s.getEmptyBeaconBlockForSlot(st, blkSlot) | ||
blk, err := s.getEmptyBeaconBlockForSlot(st, blkSlot) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
@@ -95,9 +93,6 @@ func (s *Service) BuildBlockAndSidecars( | |
if err != nil { | ||
return nil, nil, err | ||
} | ||
if envelope == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check is not necessary since all code path leading here do intercept the condition |
||
return nil, nil, ErrNilPayload | ||
} | ||
|
||
// We have to assemble the block body prior to producing the sidecars | ||
// since we need to generate the inclusion proofs. | ||
|
@@ -117,13 +112,13 @@ func (s *Service) BuildBlockAndSidecars( | |
} | ||
|
||
// Craft the signature and signed beacon block. | ||
signedBlk, err = ctypes.NewSignedBeaconBlock(blk, forkData, s.chainSpec, s.signer) | ||
signedBlk, err := ctypes.NewSignedBeaconBlock(blk, forkData, s.chainSpec, s.signer) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
// Produce blob sidecars with new StateRoot | ||
sidecars, err = s.blobFactory.BuildSidecars(signedBlk, envelope.GetBlobsBundle()) | ||
sidecars, err := s.blobFactory.BuildSidecars(signedBlk, envelope.GetBlobsBundle()) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
@@ -221,12 +216,11 @@ func (s *Service) retrieveExecutionPayload( | |
// TODO: Add external block builders to this flow. | ||
// | ||
// Get the payload for the block. | ||
envelope, err := s.localPayloadBuilder. | ||
RetrievePayload( | ||
ctx, | ||
blk.GetSlot(), | ||
blk.GetParentBlockRoot(), | ||
) | ||
envelope, err := s.localPayloadBuilder.RetrievePayload( | ||
ctx, | ||
blk.GetSlot(), | ||
blk.GetParentBlockRoot(), | ||
) | ||
if err == nil { | ||
return envelope, nil | ||
} | ||
|
@@ -247,8 +241,7 @@ func (s *Service) retrieveExecutionPayload( | |
|
||
// The latest execution payload header will be from the previous block | ||
// during the block building phase. | ||
var lph *ctypes.ExecutionPayloadHeader | ||
lph, err = st.GetLatestExecutionPayloadHeader() | ||
lph, err := st.GetLatestExecutionPayloadHeader() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,9 +50,6 @@ type Service struct { | |
// Building blocks are done by submitting forkchoice updates through. | ||
// The local Builder. | ||
localPayloadBuilder PayloadBuilder | ||
// remotePayloadBuilders represents a list of remote block builders, these | ||
// builders are connected to other execution clients via the EngineAPI. | ||
remotePayloadBuilders []PayloadBuilder | ||
Comment on lines
-53
to
-55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure what is this for, but not really used. Dropped |
||
// metrics is a metrics collector. | ||
metrics *validatorMetrics | ||
} | ||
|
@@ -67,20 +64,18 @@ func NewService( | |
signer crypto.BLSSigner, | ||
blobFactory BlobFactory, | ||
localPayloadBuilder PayloadBuilder, | ||
remotePayloadBuilders []PayloadBuilder, | ||
ts TelemetrySink, | ||
) *Service { | ||
return &Service{ | ||
cfg: cfg, | ||
logger: logger, | ||
sb: sb, | ||
chainSpec: chainSpec, | ||
signer: signer, | ||
stateProcessor: stateProcessor, | ||
blobFactory: blobFactory, | ||
localPayloadBuilder: localPayloadBuilder, | ||
remotePayloadBuilders: remotePayloadBuilders, | ||
metrics: newValidatorMetrics(ts), | ||
cfg: cfg, | ||
logger: logger, | ||
sb: sb, | ||
chainSpec: chainSpec, | ||
signer: signer, | ||
stateProcessor: stateProcessor, | ||
blobFactory: blobFactory, | ||
localPayloadBuilder: localPayloadBuilder, | ||
metrics: newValidatorMetrics(ts), | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,8 @@ implementation = "{{.BeaconKit.KZG.Implementation}}" | |
[beacon-kit.payload-builder] | ||
# Enabled determines if the local payload builder is enabled. | ||
# It should be enabled for validators, but it can be disabled | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hopefully this clarifies how this variable should be set |
||
# for full nodes. | ||
enabled = {{ .BeaconKit.PayloadBuilder.Enabled }} | ||
# Post bellatrix, this address will receive the transaction fees produced by any blocks | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,17 +142,14 @@ func (s *Client) GetPayloadV3( | |
) (ctypes.BuiltExecutionPayloadEnv, error) { | ||
var t *ctypes.ExecutionPayload | ||
result := &ctypes.ExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1[ | ||
eip4844.KZGCommitment, eip4844.KZGProof, eip4844.Blob, | ||
eip4844.KZGCommitment, | ||
eip4844.KZGProof, | ||
eip4844.Blob, | ||
]]{ | ||
ExecutionPayload: t.Empty(version.Deneb), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is one of key point of this cleanup: ExecutionPayload is never nil, cause Empty is the default empty |
||
} | ||
|
||
if err := s.Call( | ||
ctx, result, GetPayloadMethodV3, payloadID, | ||
); err != nil { | ||
return nil, err | ||
} | ||
return result, nil | ||
return result, s.Call(ctx, result, GetPayloadMethodV3, payloadID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit for readability, don't feel strongly about this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer how it was actually, think it was slightly more readable |
||
} | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,26 +47,27 @@ func (pb *PayloadBuilder) RequestPayloadAsync( | |
} | ||
|
||
if payloadID, found := pb.pc.Get(slot, parentBlockRoot); found { | ||
pb.logger.Warn( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure why this is warning, I don't think this is an error condition really? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it should be for validators since if optimistic build is enabled, still we should probably revert to info |
||
pb.logger.Info( | ||
"aborting payload build; payload already exists in cache", | ||
"for_slot", | ||
slot.Base10(), | ||
"parent_block_root", | ||
parentBlockRoot, | ||
"for_slot", slot.Base10(), | ||
"parent_block_root", parentBlockRoot, | ||
) | ||
return &payloadID, nil | ||
} | ||
|
||
// Assemble the payload attributes. | ||
attrs, err := pb.attributesFactory. | ||
BuildPayloadAttributes(st, slot, timestamp, parentBlockRoot) | ||
attrs, err := pb.attributesFactory.BuildPayloadAttributes( | ||
st, | ||
slot, | ||
timestamp, | ||
parentBlockRoot, | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Submit the forkchoice update to the execution client. | ||
var payloadID *engineprimitives.PayloadID | ||
payloadID, _, err = pb.ee.NotifyForkchoiceUpdate( | ||
payloadID, _, err := pb.ee.NotifyForkchoiceUpdate( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought this would shadow the |
||
ctx, &ctypes.ForkchoiceUpdateRequest{ | ||
State: &engineprimitives.ForkchoiceStateV1{ | ||
HeadBlockHash: headEth1BlockHash, | ||
|
@@ -166,29 +167,9 @@ func (pb *PayloadBuilder) RetrievePayload( | |
return nil, err | ||
} | ||
|
||
overrideBuilder := envelope.ShouldOverrideBuilder() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. below is just stuff for logging. I consolidated it slightly |
||
args := []any{ | ||
"for_slot", slot.Base10(), | ||
"override_builder", overrideBuilder, | ||
} | ||
|
||
payload := envelope.GetExecutionPayload() | ||
if !payload.IsNil() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check does not make sense. Note that we use payload below, without checking if is nil |
||
args = append(args, | ||
"payload_block_hash", payload.GetBlockHash(), | ||
"parent_hash", payload.GetParentHash(), | ||
) | ||
} | ||
|
||
blobsBundle := envelope.GetBlobsBundle() | ||
if blobsBundle != nil { | ||
args = append(args, "num_blobs", len(blobsBundle.GetBlobs())) | ||
} | ||
|
||
pb.logger.Info("Payload retrieved from local builder", args...) | ||
|
||
// If the payload was built by a different builder, something is | ||
// wrong the EL<>CL setup. | ||
payload := envelope.GetExecutionPayload() | ||
if payload.GetFeeRecipient() != pb.cfg.SuggestedFeeRecipient { | ||
pb.logger.Warn( | ||
"Payload fee recipient does not match suggested fee recipient - "+ | ||
|
@@ -197,6 +178,19 @@ func (pb *PayloadBuilder) RetrievePayload( | |
"suggested_fee_recipient", pb.cfg.SuggestedFeeRecipient, | ||
) | ||
} | ||
|
||
// log some data | ||
args := []any{ | ||
"for_slot", slot.Base10(), | ||
"override_builder", envelope.ShouldOverrideBuilder(), | ||
"payload_block_hash", payload.GetBlockHash(), | ||
"parent_hash", payload.GetParentHash(), | ||
} | ||
if blobsBundle := envelope.GetBlobsBundle(); blobsBundle != nil { | ||
args = append(args, "num_blobs", len(blobsBundle.GetBlobs())) | ||
} | ||
pb.logger.Info("Payload retrieved from local builder", args...) | ||
|
||
return envelope, err | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a minor optimization: if block building is disabled (as it should be, e.g. in full nodes) we could return early here.
This is currently only done in
retrieveExecutionPayload
so we partially build the block, to reject it allThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: do we know if PrepareProposal is ever called for a non-validator node?