merge with upstream

This commit is contained in:
realbigsean
2022-11-22 18:38:30 -05:00
70 changed files with 1521 additions and 761 deletions

View File

@@ -1 +1,2 @@
#[allow(clippy::module_inception)]
pub mod eip4844;

View File

@@ -6,8 +6,8 @@ use ssz::Decode;
use ssz_types::VariableList;
use types::consts::eip4844::{BLOB_TX_TYPE, VERSIONED_HASH_VERSION_KZG};
use types::{
AbstractExecPayload, BeaconBlockBodyRef, EthSpec, ExecPayload, FullPayload, FullPayloadRef,
KzgCommitment, Transaction, Transactions, VersionedHash,
AbstractExecPayload, BeaconBlockBodyRef, EthSpec, ExecPayload, KzgCommitment, Transaction,
Transactions, VersionedHash,
};
pub fn process_blob_kzg_commitments<T: EthSpec, Payload: AbstractExecPayload<T>>(
@@ -35,7 +35,7 @@ pub fn verify_kzg_commitments_against_transactions<T: EthSpec>(
let nested_iter = transactions
.into_iter()
.filter(|tx| {
tx.get(0)
tx.first()
.map(|tx_type| *tx_type == BLOB_TX_TYPE)
.unwrap_or(false)
})

View File

@@ -49,6 +49,10 @@ pub enum BlockProcessingError {
index: usize,
reason: ExitInvalid,
},
BlsExecutionChangeInvalid {
index: usize,
reason: BlsExecutionChangeInvalid,
},
SyncAggregateInvalid {
reason: SyncAggregateInvalid,
},
@@ -74,6 +78,10 @@ pub enum BlockProcessingError {
},
ExecutionInvalid,
ConsensusContext(ContextError),
WithdrawalsRootMismatch {
expected: Hash256,
found: Hash256,
},
BlobVersionHashMismatch,
/// The number of commitments in blob transactions in the payload does not match the number
/// of commitments in the block.
@@ -86,6 +94,7 @@ pub enum BlockProcessingError {
index: usize,
length: usize,
},
WithdrawalCredentialsInvalid,
}
impl From<BeaconStateError> for BlockProcessingError {
@@ -180,7 +189,8 @@ impl_into_block_processing_error_with_index!(
IndexedAttestationInvalid,
AttestationInvalid,
DepositInvalid,
ExitInvalid
ExitInvalid,
BlsExecutionChangeInvalid
);
pub type HeaderValidationError = BlockOperationError<HeaderInvalid>;
@@ -190,6 +200,7 @@ pub type AttestationValidationError = BlockOperationError<AttestationInvalid>;
pub type SyncCommitteeMessageValidationError = BlockOperationError<SyncAggregateInvalid>;
pub type DepositValidationError = BlockOperationError<DepositInvalid>;
pub type ExitValidationError = BlockOperationError<ExitInvalid>;
pub type BlsExecutionChangeValidationError = BlockOperationError<BlsExecutionChangeInvalid>;
#[derive(Debug, PartialEq, Clone)]
pub enum BlockOperationError<T> {
@@ -405,6 +416,18 @@ pub enum ExitInvalid {
SignatureSetError(SignatureSetError),
}
#[derive(Debug, PartialEq, Clone)]
pub enum BlsExecutionChangeInvalid {
/// The specified validator is not in the state's validator registry.
ValidatorUnknown(u64),
/// Validator does not have BLS Withdrawal credentials before this change
NonBlsWithdrawalCredentials,
/// Provided BLS pubkey does not match withdrawal credentials
WithdrawalCredentialsMismatch,
/// The signature is invalid
BadSignature,
}
#[derive(Debug, PartialEq, Clone)]
pub enum SyncAggregateInvalid {
/// One or more of the aggregate public keys is invalid.

View File

@@ -33,6 +33,12 @@ pub fn process_operations<'a, T: EthSpec, Payload: AbstractExecPayload<T>>(
process_attestations(state, block_body, verify_signatures, ctxt, spec)?;
process_deposits(state, block_body.deposits(), spec)?;
process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?;
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))]
if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() {
process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?;
}
Ok(())
}
@@ -279,6 +285,32 @@ pub fn process_exits<T: EthSpec>(
Ok(())
}
/// Validates each `bls_to_execution_change` and updates the state
///
/// Returns `Ok(())` if the validation and state updates completed successfully. Otherwise returs
/// an `Err` describing the invalid object or cause of failure.
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))]
pub fn process_bls_to_execution_changes<T: EthSpec>(
state: &mut BeaconState<T>,
bls_to_execution_changes: &[SignedBlsToExecutionChange],
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
for (i, signed_address_change) in bls_to_execution_changes.iter().enumerate() {
verify_bls_to_execution_change(state, signed_address_change, verify_signatures, spec)
.map_err(|e| e.into_with_index(i))?;
state
.get_validator_mut(signed_address_change.message.validator_index as usize)?
.change_withdrawal_credentials(
&signed_address_change.message.to_execution_address,
spec,
);
}
Ok(())
}
/// Validates each `Deposit` and updates the state, short-circuiting on an invalid object.
///
/// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns

View File

@@ -11,8 +11,8 @@ use types::{
BeaconStateError, ChainSpec, DepositData, Domain, Epoch, EthSpec, Fork, Hash256,
InconsistentFork, IndexedAttestation, ProposerSlashing, PublicKey, PublicKeyBytes, Signature,
SignedAggregateAndProof, SignedBeaconBlock, SignedBeaconBlockHeader,
SignedContributionAndProof, SignedRoot, SignedVoluntaryExit, SigningData, Slot, SyncAggregate,
SyncAggregatorSelectionData, Unsigned,
SignedBlsToExecutionChange, SignedContributionAndProof, SignedRoot, SignedVoluntaryExit,
SigningData, Slot, SyncAggregate, SyncAggregatorSelectionData, Unsigned,
};
pub type Result<T> = std::result::Result<T, Error>;
@@ -156,6 +156,33 @@ where
))
}
pub fn bls_execution_change_signature_set<'a, T: EthSpec>(
state: &'a BeaconState<T>,
signed_address_change: &'a SignedBlsToExecutionChange,
spec: &'a ChainSpec,
) -> Result<SignatureSet<'a>> {
let domain = spec.get_domain(
state.current_epoch(),
Domain::BlsToExecutionChange,
&state.fork(),
state.genesis_validators_root(),
);
let message = signed_address_change.message.signing_root(domain);
let signing_key = Cow::Owned(
signed_address_change
.message
.from_bls_pubkey
.decompress()
.map_err(|_| Error::PublicKeyDecompressionFailed)?,
);
Ok(SignatureSet::single_pubkey(
&signed_address_change.signature,
signing_key,
message,
))
}
/// A signature set that is valid if the block proposers randao reveal signature is correct.
pub fn randao_signature_set<'a, T, F, Payload: AbstractExecPayload<T>>(
state: &'a BeaconState<T>,

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().get(1..) == pubkey_hash.get(1..),
Invalid::WithdrawalCredentialsMismatch
);
if verify_signatures.is_true() {
verify!(
bls_execution_change_signature_set(state, signed_address_change, spec)?.verify(),
Invalid::BadSignature
);
}
Ok(())
}