-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Add proper gas limit check through local computation #14707
Changes from all commits
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 | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -51,6 +51,7 @@ var emptyTransactionsRoot = [32]byte{127, 254, 36, 30, 166, 1, 135, 253, 176, 24 | |||||||||||||||||||||||||||||||||||
// blockBuilderTimeout is the maximum amount of time allowed for a block builder to respond to a | ||||||||||||||||||||||||||||||||||||
// block request. This value is known as `BUILDER_PROPOSAL_DELAY_TOLERANCE` in builder spec. | ||||||||||||||||||||||||||||||||||||
const blockBuilderTimeout = 1 * time.Second | ||||||||||||||||||||||||||||||||||||
const gasLimitAdjustmentFactor = 1024 | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Sets the execution data for the block. Execution data can come from local EL client or remote builder depends on validator registration and circuit breaker conditions. | ||||||||||||||||||||||||||||||||||||
func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, local *blocks.GetPayloadResponse, bid builder.Bid, builderBoostFactor primitives.Gwei) (primitives.Wei, *enginev1.BlobsBundle, error) { | ||||||||||||||||||||||||||||||||||||
|
@@ -170,7 +171,11 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc | |||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// This function retrieves the payload header and kzg commitments given the slot number and the validator index. | ||||||||||||||||||||||||||||||||||||
// It's a no-op if the latest head block is not versioned bellatrix. | ||||||||||||||||||||||||||||||||||||
func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitives.Slot, idx primitives.ValidatorIndex) (builder.Bid, error) { | ||||||||||||||||||||||||||||||||||||
func (vs *Server) getPayloadHeaderFromBuilder( | ||||||||||||||||||||||||||||||||||||
ctx context.Context, | ||||||||||||||||||||||||||||||||||||
slot primitives.Slot, | ||||||||||||||||||||||||||||||||||||
idx primitives.ValidatorIndex, | ||||||||||||||||||||||||||||||||||||
parentGasLimit uint64) (builder.Bid, error) { | ||||||||||||||||||||||||||||||||||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.getPayloadHeaderFromBuilder") | ||||||||||||||||||||||||||||||||||||
defer span.End() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
@@ -243,6 +248,16 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitiv | |||||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("incorrect parent hash %#x != %#x", header.ParentHash(), h.BlockHash()) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
reg, err := vs.BlockBuilder.RegistrationByValidatorID(ctx, idx) | ||||||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||||||
log.WithError(err).Warn("Proposer: failed to get registration by validator ID, could not check gas limit") | ||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||
gasLimit := expectedGasLimit(parentGasLimit, reg.GasLimit) | ||||||||||||||||||||||||||||||||||||
if gasLimit != header.GasLimit() { | ||||||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("incorrect header gas limit %d != %d", gasLimit, header.GasLimit()) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
Comment on lines
+251
to
+259
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. You don't seem to need this else either:
Suggested change
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 think you need the else, we dont want to call 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. reg is used so if there' s an error the call to |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
t, err := slots.ToTime(uint64(vs.TimeFetcher.GenesisTime().Unix()), slot) | ||||||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||||||
return nil, err | ||||||||||||||||||||||||||||||||||||
|
@@ -393,3 +408,32 @@ func setExecution(blk interfaces.SignedBeaconBlock, execution interfaces.Executi | |||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Calculates expected gas limit based on parent gas limit and target gas limit. | ||||||||||||||||||||||||||||||||||||
// Spec code: | ||||||||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||||||||
// def expected_gas_limit(parent_gas_limit, target_gas_limit, adjustment_factor): | ||||||||||||||||||||||||||||||||||||
// max_gas_limit_difference = (parent_gas_limit // adjustment_factor) - 1 | ||||||||||||||||||||||||||||||||||||
// if target_gas_limit > parent_gas_limit: | ||||||||||||||||||||||||||||||||||||
// gas_diff = target_gas_limit - parent_gas_limit | ||||||||||||||||||||||||||||||||||||
// return parent_gas_limit + min(gas_diff, max_gas_limit_difference) | ||||||||||||||||||||||||||||||||||||
// else: | ||||||||||||||||||||||||||||||||||||
// gas_diff = parent_gas_limit - target_gas_limit | ||||||||||||||||||||||||||||||||||||
// return parent_gas_limit - min(gas_diff, max_gas_limit_difference) | ||||||||||||||||||||||||||||||||||||
func expectedGasLimit(parentGasLimit, proposerGasLimit uint64) uint64 { | ||||||||||||||||||||||||||||||||||||
maxGasLimitDiff := uint64(0) | ||||||||||||||||||||||||||||||||||||
if parentGasLimit > gasLimitAdjustmentFactor { | ||||||||||||||||||||||||||||||||||||
maxGasLimitDiff = parentGasLimit/gasLimitAdjustmentFactor - 1 | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
if proposerGasLimit > parentGasLimit { | ||||||||||||||||||||||||||||||||||||
if proposerGasLimit-parentGasLimit > maxGasLimitDiff { | ||||||||||||||||||||||||||||||||||||
return parentGasLimit + maxGasLimitDiff | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return proposerGasLimit | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
if parentGasLimit-proposerGasLimit > maxGasLimitDiff { | ||||||||||||||||||||||||||||||||||||
return parentGasLimit - maxGasLimitDiff | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return proposerGasLimit | ||||||||||||||||||||||||||||||||||||
} |
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.
Does the registration cache handle the case where the validator does not include a value?
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.
I think so. I went through the code as my understanding: the
DefaultBuilderGasLimit
is initially set inconfig.go
:It is then defined as 30M in
mainnet_config.go
:The beacon node does not provide a flag to set this gas limit, and it is not part of the consensus spec configuration. Instead, it is hard-coded in the client. The
DefaultBuilderGasLimit
is also defined as a default in the validator'sflag.go
. If the validator does not specify the--suggested-gas-limit
flag, the value inmainnet_config.go
overrides it:The
DefaultBuilderGasLimit
is used inproposer_setting.go
'sgetProposerSettings
function. This function displays or recreates the currently applied proposer settings under the validator's custom flags:In
loader.go
, theDefaultBuilderGasLimit
ensures that the default gas limit applies if the--suggested-gas-limit
flag is not set. It is then saved to the proposer settings at startup when registering for the validator node service:The
SaveProposerSettings
function is called within theLoad
method ofsettingsLoader
inloader.go
. This step saves the default gas limit to the proposer settings file:When registering the validator client, the system ensures that the proposer settings with the correct default gas limit are stored in the database:
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.
Not sure I get it right but it seems there is something confusing here, when using
--proposer-settings-file
at the validator level, if in the file if there is:When using
--suggested-fee-recipient=ZZZZ
, my_key will still propose onYYYY
(proposer settings file has priority over flag).However, when using
--suggested-gas-limit=10
, my_key will use the flag override instead of43
(flag has priority for gas limit over proposer settings).In processBuilderConfig, gas limit is overridden by the flag while the fee recipient is not:
Also, if the user specifies for
my_key
a gas limit but no fee-recipient, it seems no fee-recipient is used? (or maybe later in the hot-path it defaults to the flag?).It could make sense to align both behavior (to always have the file override the flags).
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.
yes there's a bug there, similar bug: #14721
unrelated to this PR though so will merge this PR and fix that today