mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 11:22:56 +00:00
Gloas payload bid consensus (#8801)
- [x] Consensus changes for execution payload bids - [x] EF tests for bids (and `block_header` -- no changes required). Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
This commit is contained in:
@@ -99,6 +99,9 @@ pub enum BlockProcessingError {
|
||||
IncorrectExpectedWithdrawalsVariant,
|
||||
MissingLastWithdrawal,
|
||||
PendingAttestationInElectra,
|
||||
ExecutionPayloadBidInvalid {
|
||||
reason: ExecutionPayloadBidInvalid,
|
||||
},
|
||||
/// Builder payment index out of bounds (Gloas)
|
||||
BuilderPaymentIndexOutOfBounds(usize),
|
||||
}
|
||||
@@ -157,6 +160,12 @@ impl From<milhouse::Error> for BlockProcessingError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExecutionPayloadBidInvalid> for BlockProcessingError {
|
||||
fn from(reason: ExecutionPayloadBidInvalid) -> Self {
|
||||
Self::ExecutionPayloadBidInvalid { reason }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
|
||||
fn from(e: BlockOperationError<HeaderInvalid>) -> BlockProcessingError {
|
||||
match e {
|
||||
@@ -452,6 +461,38 @@ pub enum ExitInvalid {
|
||||
PendingWithdrawalInQueue(u64),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum ExecutionPayloadBidInvalid {
|
||||
/// The validator set a non-zero amount for a self-build.
|
||||
SelfBuildNonZeroAmount,
|
||||
/// The signature is invalid.
|
||||
BadSignature,
|
||||
/// The builder is not active.
|
||||
BuilderNotActive(u64),
|
||||
/// The builder has insufficient balance to cover the bid
|
||||
InsufficientBalance {
|
||||
builder_index: u64,
|
||||
builder_balance: u64,
|
||||
bid_value: u64,
|
||||
},
|
||||
/// Bid slot doesn't match block slot
|
||||
SlotMismatch { bid_slot: Slot, block_slot: Slot },
|
||||
/// The bid's parent block hash doesn't match the state's latest block hash
|
||||
ParentBlockHashMismatch {
|
||||
state_block_hash: ExecutionBlockHash,
|
||||
bid_parent_hash: ExecutionBlockHash,
|
||||
},
|
||||
/// The bid's parent block root doesn't match the block's parent root
|
||||
ParentBlockRootMismatch {
|
||||
block_parent_root: Hash256,
|
||||
bid_parent_root: Hash256,
|
||||
},
|
||||
/// The bid's prev randao doesn't match the state.
|
||||
PrevRandaoMismatch { expected: Hash256, bid: Hash256 },
|
||||
/// The bid contains more than the maximum number of kzg blob commitments.
|
||||
ExcessBlobCommitments { max: usize, bid: usize },
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum BlsExecutionChangeInvalid {
|
||||
/// The specified validator is not in the state's validator registry.
|
||||
|
||||
@@ -9,11 +9,12 @@ use tree_hash::TreeHash;
|
||||
use typenum::Unsigned;
|
||||
use types::{
|
||||
AbstractExecPayload, AttesterSlashingRef, BeaconBlockRef, BeaconState, BeaconStateError,
|
||||
ChainSpec, DepositData, Domain, Epoch, EthSpec, Fork, Hash256, InconsistentFork,
|
||||
BuilderIndex, ChainSpec, DepositData, Domain, Epoch, EthSpec, Fork, Hash256, InconsistentFork,
|
||||
IndexedAttestation, IndexedAttestationRef, ProposerSlashing, SignedAggregateAndProof,
|
||||
SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlsToExecutionChange,
|
||||
SignedContributionAndProof, SignedRoot, SignedVoluntaryExit, SigningData, Slot, SyncAggregate,
|
||||
SyncAggregatorSelectionData,
|
||||
SignedContributionAndProof, SignedExecutionPayloadBid, SignedRoot, SignedVoluntaryExit,
|
||||
SigningData, Slot, SyncAggregate, SyncAggregatorSelectionData,
|
||||
consts::gloas::BUILDER_INDEX_SELF_BUILD,
|
||||
};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@@ -28,6 +29,9 @@ pub enum Error {
|
||||
/// Attempted to find the public key of a validator that does not exist. You cannot distinguish
|
||||
/// between an error and an invalid block in this case.
|
||||
ValidatorUnknown(u64),
|
||||
/// Attempted to find the public key of a builder that does not exist. You cannot distinguish
|
||||
/// between an error and an invalid block in this case.
|
||||
BuilderUnknown(BuilderIndex),
|
||||
/// Attempted to find the public key of a validator that does not exist. You cannot distinguish
|
||||
/// between an error and an invalid block in this case.
|
||||
ValidatorPubkeyUnknown(PublicKeyBytes),
|
||||
@@ -53,7 +57,7 @@ impl From<BeaconStateError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to get a public key from a `state`.
|
||||
/// Helper function to get a validator public key from a `state`.
|
||||
pub fn get_pubkey_from_state<E>(
|
||||
state: &BeaconState<E>,
|
||||
validator_index: usize,
|
||||
@@ -71,6 +75,25 @@ where
|
||||
.map(Cow::Owned)
|
||||
}
|
||||
|
||||
/// Helper function to get a builder public key from a `state`.
|
||||
pub fn get_builder_pubkey_from_state<E>(
|
||||
state: &BeaconState<E>,
|
||||
builder_index: BuilderIndex,
|
||||
) -> Option<Cow<'_, PublicKey>>
|
||||
where
|
||||
E: EthSpec,
|
||||
{
|
||||
state
|
||||
.builders()
|
||||
.ok()?
|
||||
.get(builder_index as usize)
|
||||
.and_then(|b| {
|
||||
let pk: Option<PublicKey> = b.pubkey.decompress().ok();
|
||||
pk
|
||||
})
|
||||
.map(Cow::Owned)
|
||||
}
|
||||
|
||||
/// A signature set that is valid if a block was signed by the expected block producer.
|
||||
pub fn block_proposal_signature_set<'a, E, F, Payload: AbstractExecPayload<E>>(
|
||||
state: &'a BeaconState<E>,
|
||||
@@ -332,6 +355,41 @@ where
|
||||
Ok(SignatureSet::multiple_pubkeys(signature, pubkeys, message))
|
||||
}
|
||||
|
||||
pub fn execution_payload_bid_signature_set<'a, E, F>(
|
||||
state: &'a BeaconState<E>,
|
||||
get_builder_pubkey: F,
|
||||
signed_execution_payload_bid: &'a SignedExecutionPayloadBid<E>,
|
||||
spec: &'a ChainSpec,
|
||||
) -> Result<Option<SignatureSet<'a>>>
|
||||
where
|
||||
E: EthSpec,
|
||||
F: Fn(BuilderIndex) -> Option<Cow<'a, PublicKey>>,
|
||||
{
|
||||
let execution_payload_bid = &signed_execution_payload_bid.message;
|
||||
let builder_index = execution_payload_bid.builder_index;
|
||||
if builder_index == BUILDER_INDEX_SELF_BUILD {
|
||||
// No signatures to verify in case of a self-build, but consensus code MUST check that
|
||||
// the signature is the point at infinity.
|
||||
// See `process_execution_payload_bid`.
|
||||
return Ok(None);
|
||||
}
|
||||
let domain = spec.get_domain(
|
||||
state.current_epoch(),
|
||||
Domain::BeaconBuilder,
|
||||
&state.fork(),
|
||||
state.genesis_validators_root(),
|
||||
);
|
||||
|
||||
let pubkey = get_builder_pubkey(builder_index).ok_or(Error::BuilderUnknown(builder_index))?;
|
||||
let message = execution_payload_bid.signing_root(domain);
|
||||
|
||||
Ok(Some(SignatureSet::single_pubkey(
|
||||
&signed_execution_payload_bid.signature,
|
||||
pubkey,
|
||||
message,
|
||||
)))
|
||||
}
|
||||
|
||||
/// Returns the signature set for the given `attester_slashing` and corresponding `pubkeys`.
|
||||
pub fn attester_slashing_signature_sets<'a, E, F>(
|
||||
state: &'a BeaconState<E>,
|
||||
|
||||
Reference in New Issue
Block a user