mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-28 02:03:32 +00:00
Merge branch 'unstable' into off-4844
This commit is contained in:
@@ -413,18 +413,18 @@ where
|
||||
AttestationShufflingId::new(anchor_block_root, anchor_state, RelativeEpoch::Next)
|
||||
.map_err(Error::BeaconStateError)?;
|
||||
|
||||
// Default any non-merge execution block hashes to 0x000..000.
|
||||
let execution_status = anchor_block.message_merge().map_or_else(
|
||||
|()| ExecutionStatus::irrelevant(),
|
||||
|message| {
|
||||
let execution_payload = &message.body.execution_payload;
|
||||
if execution_payload == &<_>::default() {
|
||||
let execution_status = anchor_block.message().execution_payload().map_or_else(
|
||||
// If the block doesn't have an execution payload then it can't have
|
||||
// execution enabled.
|
||||
|_| ExecutionStatus::irrelevant(),
|
||||
|execution_payload| {
|
||||
if execution_payload.is_default_with_empty_roots() {
|
||||
// A default payload does not have execution enabled.
|
||||
ExecutionStatus::irrelevant()
|
||||
} else {
|
||||
// Assume that this payload is valid, since the anchor should be a trusted block and
|
||||
// state.
|
||||
ExecutionStatus::Valid(message.body.execution_payload.block_hash())
|
||||
ExecutionStatus::Valid(execution_payload.block_hash())
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -857,8 +857,8 @@ where
|
||||
(parent_justified, parent_finalized)
|
||||
} else {
|
||||
let justification_and_finalization_state = match block {
|
||||
// FIXME: verify this is correct for Capella/Eip4844 because
|
||||
// epoch processing changes in Capella..
|
||||
// TODO(eip4844): Ensure that the final specification
|
||||
// does not substantially modify per epoch processing.
|
||||
BeaconBlockRef::Eip4844(_)
|
||||
| BeaconBlockRef::Capella(_)
|
||||
| BeaconBlockRef::Merge(_)
|
||||
|
||||
@@ -176,6 +176,15 @@ impl<'a, T, N: Unsigned> IntoIterator for &'a VariableList<T, N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, N: Unsigned> IntoIterator for VariableList<T, N> {
|
||||
type Item = T;
|
||||
type IntoIter = std::vec::IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.vec.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, N: Unsigned> tree_hash::TreeHash for VariableList<T, N>
|
||||
where
|
||||
T: tree_hash::TreeHash,
|
||||
|
||||
@@ -180,7 +180,15 @@ pub fn per_block_processing<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
)?;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
process_blob_kzg_commitments(block.body(), ctxt)?;
|
||||
=======
|
||||
// Eip4844 specifications are not yet released so additional care is taken
|
||||
// to ensure the code does not run in production.
|
||||
if matches!(block, BeaconBlockRef::Eip4844(_)) {
|
||||
process_blob_kzg_commitments(block.body())?;
|
||||
}
|
||||
>>>>>>> unstable
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ 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.
|
||||
/// Indicates if a `BlsToExecutionChange` is valid to be included in a block,
|
||||
/// where the block is being applied to 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>(
|
||||
|
||||
@@ -485,6 +485,52 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> EmptyBlock for BeaconBlockMerg
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> BeaconBlockCapella<T, Payload> {
|
||||
/// Return a Capella block where the block has maximum size.
|
||||
pub fn full(spec: &ChainSpec) -> Self {
|
||||
let base_block: BeaconBlockBase<_, Payload> = BeaconBlockBase::full(spec);
|
||||
let bls_to_execution_changes = vec![
|
||||
SignedBlsToExecutionChange {
|
||||
message: BlsToExecutionChange {
|
||||
validator_index: 0,
|
||||
from_bls_pubkey: PublicKeyBytes::empty(),
|
||||
to_execution_address: Address::zero(),
|
||||
},
|
||||
signature: Signature::empty()
|
||||
};
|
||||
T::max_bls_to_execution_changes()
|
||||
]
|
||||
.into();
|
||||
let sync_aggregate = SyncAggregate {
|
||||
sync_committee_signature: AggregateSignature::empty(),
|
||||
sync_committee_bits: BitVector::default(),
|
||||
};
|
||||
BeaconBlockCapella {
|
||||
slot: spec.genesis_slot,
|
||||
proposer_index: 0,
|
||||
parent_root: Hash256::zero(),
|
||||
state_root: Hash256::zero(),
|
||||
body: BeaconBlockBodyCapella {
|
||||
proposer_slashings: base_block.body.proposer_slashings,
|
||||
attester_slashings: base_block.body.attester_slashings,
|
||||
attestations: base_block.body.attestations,
|
||||
deposits: base_block.body.deposits,
|
||||
voluntary_exits: base_block.body.voluntary_exits,
|
||||
bls_to_execution_changes,
|
||||
sync_aggregate,
|
||||
randao_reveal: Signature::empty(),
|
||||
eth1_data: Eth1Data {
|
||||
deposit_root: Hash256::zero(),
|
||||
block_hash: Hash256::zero(),
|
||||
deposit_count: 0,
|
||||
},
|
||||
graffiti: Graffiti::default(),
|
||||
execution_payload: Payload::Capella::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Payload: AbstractExecPayload<T>> EmptyBlock for BeaconBlockCapella<T, Payload> {
|
||||
/// Returns an empty Capella block to be used during genesis.
|
||||
fn empty(spec: &ChainSpec) -> Self {
|
||||
@@ -752,19 +798,65 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_capella_block() {
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
let spec = &ForkName::Capella.make_genesis_spec(MainnetEthSpec::default_spec());
|
||||
|
||||
let inner_block = BeaconBlockCapella {
|
||||
slot: Slot::random_for_test(rng),
|
||||
proposer_index: u64::random_for_test(rng),
|
||||
parent_root: Hash256::random_for_test(rng),
|
||||
state_root: Hash256::random_for_test(rng),
|
||||
body: BeaconBlockBodyCapella::random_for_test(rng),
|
||||
};
|
||||
let block = BeaconBlock::Capella(inner_block.clone());
|
||||
|
||||
test_ssz_tree_hash_pair_with(&block, &inner_block, |bytes| {
|
||||
BeaconBlock::from_ssz_bytes(bytes, spec)
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roundtrip_4844_block() {
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
let spec = &ForkName::Eip4844.make_genesis_spec(MainnetEthSpec::default_spec());
|
||||
|
||||
let inner_block = BeaconBlockEip4844 {
|
||||
slot: Slot::random_for_test(rng),
|
||||
proposer_index: u64::random_for_test(rng),
|
||||
parent_root: Hash256::random_for_test(rng),
|
||||
state_root: Hash256::random_for_test(rng),
|
||||
body: BeaconBlockBodyEip4844::random_for_test(rng),
|
||||
};
|
||||
let block = BeaconBlock::Eip4844(inner_block.clone());
|
||||
|
||||
test_ssz_tree_hash_pair_with(&block, &inner_block, |bytes| {
|
||||
BeaconBlock::from_ssz_bytes(bytes, spec)
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_base_and_altair() {
|
||||
type E = MainnetEthSpec;
|
||||
let spec = E::default_spec();
|
||||
let mut spec = E::default_spec();
|
||||
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
|
||||
let fork_epoch = spec.altair_fork_epoch.unwrap();
|
||||
let altair_fork_epoch = spec.altair_fork_epoch.unwrap();
|
||||
|
||||
let base_epoch = fork_epoch.saturating_sub(1_u64);
|
||||
let base_epoch = altair_fork_epoch.saturating_sub(1_u64);
|
||||
let base_slot = base_epoch.end_slot(E::slots_per_epoch());
|
||||
let altair_epoch = fork_epoch;
|
||||
let altair_epoch = altair_fork_epoch;
|
||||
let altair_slot = altair_epoch.start_slot(E::slots_per_epoch());
|
||||
let capella_epoch = altair_fork_epoch + 1;
|
||||
let capella_slot = capella_epoch.start_slot(E::slots_per_epoch());
|
||||
let eip4844_epoch = capella_epoch + 1;
|
||||
let eip4844_slot = eip4844_epoch.start_slot(E::slots_per_epoch());
|
||||
|
||||
spec.altair_fork_epoch = Some(altair_epoch);
|
||||
spec.capella_fork_epoch = Some(capella_epoch);
|
||||
spec.eip4844_fork_epoch = Some(eip4844_epoch);
|
||||
|
||||
// BeaconBlockBase
|
||||
{
|
||||
@@ -809,5 +901,49 @@ mod tests {
|
||||
BeaconBlock::from_ssz_bytes(&bad_altair_block.as_ssz_bytes(), &spec)
|
||||
.expect_err("bad altair block cannot be decoded");
|
||||
}
|
||||
|
||||
// BeaconBlockCapella
|
||||
{
|
||||
let good_block = BeaconBlock::Capella(BeaconBlockCapella {
|
||||
slot: capella_slot,
|
||||
..<_>::random_for_test(rng)
|
||||
});
|
||||
// It's invalid to have an Capella block with a epoch lower than the fork epoch.
|
||||
let bad_block = {
|
||||
let mut bad = good_block.clone();
|
||||
*bad.slot_mut() = altair_slot;
|
||||
bad
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec)
|
||||
.expect("good capella block can be decoded"),
|
||||
good_block
|
||||
);
|
||||
BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec)
|
||||
.expect_err("bad capella block cannot be decoded");
|
||||
}
|
||||
|
||||
// BeaconBlockEip4844
|
||||
{
|
||||
let good_block = BeaconBlock::Eip4844(BeaconBlockEip4844 {
|
||||
slot: eip4844_slot,
|
||||
..<_>::random_for_test(rng)
|
||||
});
|
||||
// It's invalid to have an Capella block with a epoch lower than the fork epoch.
|
||||
let bad_block = {
|
||||
let mut bad = good_block.clone();
|
||||
*bad.slot_mut() = capella_slot;
|
||||
bad
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec)
|
||||
.expect("good eip4844 block can be decoded"),
|
||||
good_block
|
||||
);
|
||||
BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec)
|
||||
.expect_err("bad eip4844 block cannot be decoded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,7 +710,6 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
.ok_or(Error::ShuffleIndexOutOfBounds(index))
|
||||
}
|
||||
|
||||
// TODO: check this implementation
|
||||
/// Convenience accessor for the `execution_payload_header` as an `ExecutionPayloadHeaderRef`.
|
||||
pub fn latest_execution_payload_header(&self) -> Result<ExecutionPayloadHeaderRef<T>, Error> {
|
||||
match self {
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/// Note: this object does not actually exist in the spec.
|
||||
///
|
||||
/// We use it for managing attestations that have not been aggregated.
|
||||
use super::{AttestationData, Signature};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(arbitrary::Arbitrary, Debug, Clone, PartialEq, Serialize)]
|
||||
pub struct FreeAttestation {
|
||||
pub data: AttestationData,
|
||||
pub signature: Signature,
|
||||
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
||||
pub validator_index: u64,
|
||||
}
|
||||
@@ -47,7 +47,6 @@ pub mod fork;
|
||||
pub mod fork_data;
|
||||
pub mod fork_name;
|
||||
pub mod fork_versioned_response;
|
||||
pub mod free_attestation;
|
||||
pub mod graffiti;
|
||||
pub mod historical_batch;
|
||||
pub mod historical_summary;
|
||||
@@ -154,7 +153,6 @@ pub use crate::fork_name::{ForkName, InconsistentFork};
|
||||
pub use crate::fork_versioned_response::{
|
||||
ExecutionOptimisticForkVersionedResponse, ForkVersionDeserialize, ForkVersionedResponse,
|
||||
};
|
||||
pub use crate::free_attestation::FreeAttestation;
|
||||
pub use crate::graffiti::{Graffiti, GRAFFITI_BYTES_LEN};
|
||||
pub use crate::historical_batch::HistoricalBatch;
|
||||
pub use crate::indexed_attestation::IndexedAttestation;
|
||||
|
||||
Reference in New Issue
Block a user