Fixed compiling with withdrawals enabled

This commit is contained in:
Mark Mackey 2022-11-09 19:28:14 -06:00
parent ab13f95db5
commit 2d01ae6036
10 changed files with 161 additions and 21 deletions

View File

@ -261,6 +261,8 @@ struct PartialBeaconBlock<E: EthSpec, Payload: AbstractExecPayload<E>> {
voluntary_exits: Vec<SignedVoluntaryExit>, voluntary_exits: Vec<SignedVoluntaryExit>,
sync_aggregate: Option<SyncAggregate<E>>, sync_aggregate: Option<SyncAggregate<E>>,
prepare_payload_handle: Option<PreparePayloadHandle<E, Payload>>, prepare_payload_handle: Option<PreparePayloadHandle<E, Payload>>,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: Vec<SignedBlsToExecutionChange>,
} }
pub type BeaconForkChoice<T> = ForkChoice< pub type BeaconForkChoice<T> = ForkChoice<
@ -3485,6 +3487,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?; let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?;
let deposits = eth1_chain.deposits_for_block_inclusion(&state, &eth1_data, &self.spec)?; let deposits = eth1_chain.deposits_for_block_inclusion(&state, &eth1_data, &self.spec)?;
let bls_to_execution_changes = self
.op_pool
.get_bls_to_execution_changes(&state, &self.spec);
// Iterate through the naive aggregation pool and ensure all the attestations from there // Iterate through the naive aggregation pool and ensure all the attestations from there
// are included in the operation pool. // are included in the operation pool.
@ -3642,6 +3647,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
prepare_payload_handle, prepare_payload_handle,
bls_to_execution_changes,
}) })
} }
@ -3670,6 +3676,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// this function. We can assume that the handle has already been consumed in order to // this function. We can assume that the handle has already been consumed in order to
// produce said `execution_payload`. // produce said `execution_payload`.
prepare_payload_handle: _, prepare_payload_handle: _,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
} = partial_beacon_block; } = partial_beacon_block;
let inner_block = match &state { let inner_block = match &state {
@ -3751,6 +3759,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.to_payload() .to_payload()
.try_into() .try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?, .map_err(|_| BlockProductionError::InvalidPayloadFork)?,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.into(),
}, },
}), }),
BeaconState::Eip4844(_) => BeaconBlock::Eip4844(BeaconBlockEip4844 { BeaconState::Eip4844(_) => BeaconBlock::Eip4844(BeaconBlockEip4844 {
@ -3773,6 +3783,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.to_payload() .to_payload()
.try_into() .try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?, .map_err(|_| BlockProductionError::InvalidPayloadFork)?,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.into(),
//FIXME(sean) get blobs //FIXME(sean) get blobs
blob_kzg_commitments: VariableList::from(kzg_commitments), blob_kzg_commitments: VariableList::from(kzg_commitments),
}, },

View File

@ -107,13 +107,10 @@ where
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub withdrawal_queue: VariableList<Withdrawal, T::WithdrawalQueueLimit>,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))]
pub next_withdrawal_index: u64, pub next_withdrawal_index: u64,
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub next_partial_withdrawal_validator_index: u64, pub latest_withdrawal_validator_index: u64,
} }
/// Implement the conversion function from BeaconState -> PartialBeaconState. /// Implement the conversion function from BeaconState -> PartialBeaconState.
@ -215,9 +212,8 @@ impl<T: EthSpec> PartialBeaconState<T> {
next_sync_committee, next_sync_committee,
inactivity_scores, inactivity_scores,
latest_execution_payload_header, latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index, next_withdrawal_index,
next_partial_withdrawal_validator_index latest_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))] #[cfg(not(feature = "withdrawals"))]
@ -248,9 +244,8 @@ impl<T: EthSpec> PartialBeaconState<T> {
next_sync_committee, next_sync_committee,
inactivity_scores, inactivity_scores,
latest_execution_payload_header, latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index, next_withdrawal_index,
next_partial_withdrawal_validator_index latest_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))] #[cfg(not(feature = "withdrawals"))]
@ -467,9 +462,8 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
next_sync_committee, next_sync_committee,
inactivity_scores, inactivity_scores,
latest_execution_payload_header, latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index, next_withdrawal_index,
next_partial_withdrawal_validator_index latest_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))] #[cfg(not(feature = "withdrawals"))]
@ -498,9 +492,8 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
next_sync_committee, next_sync_committee,
inactivity_scores, inactivity_scores,
latest_execution_payload_header, latest_execution_payload_header,
withdrawal_queue,
next_withdrawal_index, next_withdrawal_index,
next_partial_withdrawal_validator_index latest_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))] #[cfg(not(feature = "withdrawals"))]

View File

@ -300,7 +300,9 @@ pub fn process_bls_to_execution_changes<'a, T: EthSpec, Payload: AbstractExecPay
| BeaconBlockBodyRef::Altair(_) | BeaconBlockBodyRef::Altair(_)
| BeaconBlockBodyRef::Merge(_) => Ok(()), | BeaconBlockBodyRef::Merge(_) => Ok(()),
BeaconBlockBodyRef::Capella(_) | BeaconBlockBodyRef::Eip4844(_) => { BeaconBlockBodyRef::Capella(_) | BeaconBlockBodyRef::Eip4844(_) => {
for (i, signed_address_change) in block_body.bls_to_execution_changes()?.enumerate() { for (i, signed_address_change) in
block_body.bls_to_execution_changes()?.iter().enumerate()
{
verify_bls_to_execution_change( verify_bls_to_execution_change(
state, state,
&signed_address_change, &signed_address_change,
@ -310,9 +312,9 @@ pub fn process_bls_to_execution_changes<'a, T: EthSpec, Payload: AbstractExecPay
.map_err(|e| e.into_with_index(i))?; .map_err(|e| e.into_with_index(i))?;
state state
.get_validator_mut(signed_address_change.message.validator_index)? .get_validator_mut(signed_address_change.message.validator_index as usize)?
.change_withdrawal_credentials( .change_withdrawal_credentials(
signed_address_change.message.to_execution_address, &signed_address_change.message.to_execution_address,
spec, spec,
); );
} }

View File

@ -0,0 +1,57 @@
use super::errors::{BlockOperationError, BlsExecutionChangeInvalid as Invalid};
use crate::per_block_processing::signature_sets::bls_execution_change_signature_set;
use crate::VerifySignatures;
use eth2_hashing::hash;
use types::*;
type Result<T> = std::result::Result<T, BlockOperationError<Invalid>>;
fn error(reason: Invalid) -> BlockOperationError<Invalid> {
BlockOperationError::invalid(reason)
}
/// Indicates if a `BlsToExecutionChange` is valid to be included in a block in the current epoch of the given
/// state.
///
/// Returns `Ok(())` if the `SignedBlsToExecutionChange` is valid, otherwise indicates the reason for invalidity.
pub fn verify_bls_to_execution_change<T: EthSpec>(
state: &BeaconState<T>,
signed_address_change: &SignedBlsToExecutionChange,
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<()> {
let address_change = &signed_address_change.message;
let validator = state
.validators()
.get(address_change.validator_index as usize)
.ok_or_else(|| error(Invalid::ValidatorUnknown(address_change.validator_index)))?;
verify!(
validator
.withdrawal_credentials
.as_bytes()
.first()
.map(|byte| *byte == spec.bls_withdrawal_prefix_byte)
.unwrap_or(false),
Invalid::NonBlsWithdrawalCredentials
);
let pubkey_hash = hash(address_change.from_bls_pubkey.as_serialized());
// FIXME: Should this check be put inside the verify_signatures.is_true() condition?
// I believe that's used for fuzzing so this is a Mehdi question..
verify!(
validator.withdrawal_credentials.as_bytes()[1..] == pubkey_hash[1..],
Invalid::WithdrawalCredentialsMismatch
);
if verify_signatures.is_true() {
verify!(
bls_execution_change_signature_set(state, signed_address_change, spec,)?.verify(),
Invalid::BadSignature
);
}
Ok(())
}

View File

@ -58,11 +58,9 @@ pub fn upgrade_to_capella<E: EthSpec>(
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_capella(), latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_capella(),
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
withdrawal_queue: VariableList::empty(),
#[cfg(feature = "withdrawals")]
next_withdrawal_index: 0, next_withdrawal_index: 0,
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
next_partial_withdrawal_validator_index: 0, latest_withdrawal_validator_index: 0,
// Caches // Caches
total_active_balance: pre.total_active_balance, total_active_balance: pre.total_active_balance,
committee_caches: mem::take(&mut pre.committee_caches), committee_caches: mem::take(&mut pre.committee_caches),

View File

@ -65,11 +65,9 @@ pub fn upgrade_to_eip4844<E: EthSpec>(
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip4844(), latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip4844(),
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
withdrawal_queue: mem::take(&mut pre.withdrawal_queue),
#[cfg(feature = "withdrawals")]
next_withdrawal_index: pre.next_withdrawal_index, next_withdrawal_index: pre.next_withdrawal_index,
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
next_partial_withdrawal_validator_index: pre.next_partial_withdrawal_validator_index, latest_withdrawal_validator_index: 0,
// Caches // Caches
total_active_balance: pre.total_active_balance, total_active_balance: pre.total_active_balance,
committee_caches: mem::take(&mut pre.committee_caches), committee_caches: mem::take(&mut pre.committee_caches),

View File

@ -301,6 +301,8 @@ impl<E: EthSpec> From<BeaconBlockBodyCapella<E, FullPayload<E>>>
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload }, execution_payload: FullPayloadCapella { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
} = body; } = body;
( (
@ -317,6 +319,8 @@ impl<E: EthSpec> From<BeaconBlockBodyCapella<E, FullPayload<E>>>
execution_payload: BlindedPayloadCapella { execution_payload: BlindedPayloadCapella {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
}, },
Some(execution_payload), Some(execution_payload),
) )
@ -341,6 +345,8 @@ impl<E: EthSpec> From<BeaconBlockBodyEip4844<E, FullPayload<E>>>
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadEip4844 { execution_payload }, execution_payload: FullPayloadEip4844 { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
} = body; } = body;
@ -358,6 +364,8 @@ impl<E: EthSpec> From<BeaconBlockBodyEip4844<E, FullPayload<E>>>
execution_payload: BlindedPayloadEip4844 { execution_payload: BlindedPayloadEip4844 {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, },
Some(execution_payload), Some(execution_payload),
@ -425,6 +433,8 @@ impl<E: EthSpec> BeaconBlockBodyCapella<E, FullPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload }, execution_payload: FullPayloadCapella { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
} = self; } = self;
BeaconBlockBodyCapella { BeaconBlockBodyCapella {
@ -440,6 +450,8 @@ impl<E: EthSpec> BeaconBlockBodyCapella<E, FullPayload<E>> {
execution_payload: BlindedPayloadCapella { execution_payload: BlindedPayloadCapella {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.clone(),
} }
} }
} }
@ -457,6 +469,8 @@ impl<E: EthSpec> BeaconBlockBodyEip4844<E, FullPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadEip4844 { execution_payload }, execution_payload: FullPayloadEip4844 { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
} = self; } = self;
@ -473,6 +487,8 @@ impl<E: EthSpec> BeaconBlockBodyEip4844<E, FullPayload<E>> {
execution_payload: BlindedPayloadEip4844 { execution_payload: BlindedPayloadEip4844 {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.clone(),
blob_kzg_commitments: blob_kzg_commitments.clone(), blob_kzg_commitments: blob_kzg_commitments.clone(),
} }
} }

View File

@ -0,0 +1,30 @@
use crate::test_utils::TestRandom;
use crate::*;
use bls::PublicKeyBytes;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
use tree_hash_derive::TreeHash;
/// A deposit to potentially become a beacon chain validator.
///
/// Spec v0.12.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Debug, PartialEq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
)]
pub struct BlsToExecutionChange {
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub validator_index: u64,
pub from_bls_pubkey: PublicKeyBytes,
pub to_execution_address: Address,
}
impl SignedRoot for BlsToExecutionChange {}
#[cfg(test)]
mod tests {
use super::*;
ssz_and_tree_hash_tests!(BlsToExecutionChange);
}

View File

@ -341,6 +341,8 @@ impl<E: EthSpec> SignedBeaconBlockCapella<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: BlindedPayloadCapella { .. }, execution_payload: BlindedPayloadCapella { .. },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
}, },
}, },
signature, signature,
@ -362,6 +364,8 @@ impl<E: EthSpec> SignedBeaconBlockCapella<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload }, execution_payload: FullPayloadCapella { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
}, },
}, },
signature, signature,
@ -393,6 +397,8 @@ impl<E: EthSpec> SignedBeaconBlockEip4844<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: BlindedPayloadEip4844 { .. }, execution_payload: BlindedPayloadEip4844 { .. },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, },
}, },
@ -415,6 +421,8 @@ impl<E: EthSpec> SignedBeaconBlockEip4844<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadEip4844 { execution_payload }, execution_payload: FullPayloadEip4844 { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, },
}, },

View File

@ -0,0 +1,26 @@
use crate::test_utils::TestRandom;
use crate::*;
use bls::Signature;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
use tree_hash_derive::TreeHash;
/// A deposit to potentially become a beacon chain validator.
///
/// Spec v0.12.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Debug, PartialEq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
)]
pub struct SignedBlsToExecutionChange {
pub message: BlsToExecutionChange,
pub signature: Signature,
}
#[cfg(test)]
mod tests {
use super::*;
ssz_and_tree_hash_tests!(SignedBlsToExecutionChange);
}