Gloas process execution payload bid (#8355)

* add proces_execution_bid

* add has_builder_withdrawal_credential

* process_execution_payload_bid signature is infinity check for self-build

* process_execution_payload_bid updates per consensus spec v1.6.0-beta.1 release

* process_execution_bid to avoid expensive lookups for 0 amount bids

* verify builder not slashed even for self-building
This commit is contained in:
Shane K Moore
2025-11-06 14:02:37 -08:00
committed by GitHub
parent 4ab5a77361
commit 4dfc31c0a9
9 changed files with 316 additions and 36 deletions

View File

@@ -161,6 +161,7 @@ pub enum Error {
TotalActiveBalanceDiffUninitialized,
GeneralizedIndexNotSupported(usize),
IndexNotSupported(usize),
BuilderPendingPaymentsIndexNotSupported(usize),
InvalidFlagIndex(usize),
MerkleTreeError(merkle_proof::MerkleTreeError),
PartialWithdrawalCountInvalid(usize),

View File

@@ -159,13 +159,41 @@ impl Validator {
}
/// Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal credential.
pub fn has_compounding_withdrawal_credential(&self, spec: &ChainSpec) -> bool {
pub fn has_compounding_withdrawal_credential(
&self,
spec: &ChainSpec,
current_fork: ForkName,
) -> bool {
if current_fork.gloas_enabled() {
self.has_compounding_withdrawal_credential_gloas(spec)
} else {
self.has_compounding_withdrawal_credential_electra(spec)
}
}
/// Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal credential
pub fn has_compounding_withdrawal_credential_electra(&self, spec: &ChainSpec) -> bool {
is_compounding_withdrawal_credential(self.withdrawal_credentials, spec)
}
/// Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal credential or an 0x03 prefixed "builder" withdrawal credential
pub fn has_compounding_withdrawal_credential_gloas(&self, spec: &ChainSpec) -> bool {
is_compounding_withdrawal_credential(self.withdrawal_credentials, spec)
|| is_builder_withdrawal_credential(self.withdrawal_credentials, spec)
}
/// Check if ``validator`` has an 0x03 prefixed "builder" withdrawal credential.
pub fn has_builder_withdrawal_credential(&self, spec: &ChainSpec) -> bool {
is_builder_withdrawal_credential(self.withdrawal_credentials, spec)
}
/// Get the execution withdrawal address if this validator has one initialized.
pub fn get_execution_withdrawal_address(&self, spec: &ChainSpec) -> Option<Address> {
self.has_execution_withdrawal_credential(spec)
pub fn get_execution_withdrawal_address(
&self,
spec: &ChainSpec,
current_fork: ForkName,
) -> Option<Address> {
self.has_execution_withdrawal_credential(spec, current_fork)
.then(|| {
self.withdrawal_credentials
.as_slice()
@@ -196,7 +224,7 @@ impl Validator {
current_fork: ForkName,
) -> bool {
if current_fork.electra_enabled() {
self.is_fully_withdrawable_validator_electra(balance, epoch, spec)
self.is_fully_withdrawable_validator_electra(balance, epoch, spec, current_fork)
} else {
self.is_fully_withdrawable_validator_capella(balance, epoch, spec)
}
@@ -220,8 +248,9 @@ impl Validator {
balance: u64,
epoch: Epoch,
spec: &ChainSpec,
current_fork: ForkName,
) -> bool {
self.has_execution_withdrawal_credential(spec)
self.has_execution_withdrawal_credential(spec, current_fork)
&& self.withdrawable_epoch <= epoch
&& balance > 0
}
@@ -261,21 +290,25 @@ impl Validator {
let max_effective_balance = self.get_max_effective_balance(spec, current_fork);
let has_max_effective_balance = self.effective_balance == max_effective_balance;
let has_excess_balance = balance > max_effective_balance;
self.has_execution_withdrawal_credential(spec)
self.has_execution_withdrawal_credential(spec, current_fork)
&& has_max_effective_balance
&& has_excess_balance
}
/// Returns `true` if the validator has a 0x01 or 0x02 prefixed withdrawal credential.
pub fn has_execution_withdrawal_credential(&self, spec: &ChainSpec) -> bool {
self.has_compounding_withdrawal_credential(spec)
pub fn has_execution_withdrawal_credential(
&self,
spec: &ChainSpec,
current_fork: ForkName,
) -> bool {
self.has_compounding_withdrawal_credential(spec, current_fork)
|| self.has_eth1_withdrawal_credential(spec)
}
/// Returns the max effective balance for a validator in gwei.
pub fn get_max_effective_balance(&self, spec: &ChainSpec, current_fork: ForkName) -> u64 {
if current_fork >= ForkName::Electra {
if self.has_compounding_withdrawal_credential(spec) {
if self.has_compounding_withdrawal_credential(spec, current_fork) {
spec.max_effective_balance_electra
} else {
spec.min_activation_balance
@@ -313,6 +346,15 @@ pub fn is_compounding_withdrawal_credential(
.unwrap_or(false)
}
/// Check if the withdrawal credential has the builder withdrawal prefix (0x03).
pub fn is_builder_withdrawal_credential(withdrawal_credentials: Hash256, spec: &ChainSpec) -> bool {
withdrawal_credentials
.as_slice()
.first()
.map(|prefix_byte| *prefix_byte == spec.builder_withdrawal_prefix_byte)
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;