mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 00:42:42 +00:00
additional container logic ported
This commit is contained in:
@@ -2004,6 +2004,18 @@ impl<E: EthSpec> BeaconState<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the PTC
|
||||||
|
/// Requires the committee cache to be initialized.
|
||||||
|
/// TODO(EIP-7732): definitely gonna have to cache this..
|
||||||
|
/// TODO(EIP-7732): check this implementation against the latest spec
|
||||||
|
// https://ethereum.github.io/consensus-specs/specs/_features/eip7732/beacon-chain/#new-get_ptc
|
||||||
|
pub fn get_ptc(&self, slot: Slot) -> Result<PTC<E>, Error> {
|
||||||
|
let committee_cache = self.committee_cache_at_slot(slot)?;
|
||||||
|
let committees = committee_cache.get_beacon_committees_at_slot(slot)?;
|
||||||
|
|
||||||
|
PTC::from_committees(&committees)
|
||||||
|
}
|
||||||
|
|
||||||
/// Build all caches (except the tree hash cache), if they need to be built.
|
/// Build all caches (except the tree hash cache), if they need to be built.
|
||||||
#[instrument(skip_all, level = "debug")]
|
#[instrument(skip_all, level = "debug")]
|
||||||
pub fn build_caches(&mut self, spec: &ChainSpec) -> Result<(), Error> {
|
pub fn build_caches(&mut self, spec: &ChainSpec) -> Result<(), Error> {
|
||||||
|
|||||||
@@ -2483,9 +2483,9 @@ mod tests {
|
|||||||
spec.domain_aggregate_and_proof,
|
spec.domain_aggregate_and_proof,
|
||||||
&spec,
|
&spec,
|
||||||
);
|
);
|
||||||
|
test_domain(Domain::SyncCommittee, spec.domain_sync_committee, &spec);
|
||||||
test_domain(Domain::BeaconBuilder, spec.domain_beacon_builder, &spec);
|
test_domain(Domain::BeaconBuilder, spec.domain_beacon_builder, &spec);
|
||||||
test_domain(Domain::PTCAttester, spec.domain_ptc_attester, &spec);
|
test_domain(Domain::PTCAttester, spec.domain_ptc_attester, &spec);
|
||||||
test_domain(Domain::SyncCommittee, spec.domain_sync_committee, &spec);
|
|
||||||
|
|
||||||
// The builder domain index is zero
|
// The builder domain index is zero
|
||||||
let builder_domain_pre_mask = [0; 4];
|
let builder_domain_pre_mask = [0; 4];
|
||||||
|
|||||||
@@ -405,10 +405,12 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
Self::ProposerLookaheadSlots::to_usize()
|
Self::ProposerLookaheadSlots::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `PTCSize` constant for this specification.
|
||||||
fn ptc_size() -> usize {
|
fn ptc_size() -> usize {
|
||||||
Self::PTCSize::to_usize()
|
Self::PTCSize::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `MaxPayloadAttestations` constant for this specification.
|
||||||
fn max_payload_attestations() -> usize {
|
fn max_payload_attestations() -> usize {
|
||||||
Self::MaxPayloadAttestations::to_usize()
|
Self::MaxPayloadAttestations::to_usize()
|
||||||
}
|
}
|
||||||
@@ -484,7 +486,7 @@ impl EthSpec for MainnetEthSpec {
|
|||||||
type MaxWithdrawalRequestsPerPayload = U16;
|
type MaxWithdrawalRequestsPerPayload = U16;
|
||||||
type MaxPendingDepositsPerEpoch = U16;
|
type MaxPendingDepositsPerEpoch = U16;
|
||||||
type PTCSize = U512;
|
type PTCSize = U512;
|
||||||
type MaxPayloadAttestations = U2;
|
type MaxPayloadAttestations = U4;
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec {
|
fn default_spec() -> ChainSpec {
|
||||||
ChainSpec::mainnet()
|
ChainSpec::mainnet()
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ mod tests {
|
|||||||
spec.deneb_fork_epoch = Some(Epoch::new(4));
|
spec.deneb_fork_epoch = Some(Epoch::new(4));
|
||||||
spec.electra_fork_epoch = Some(Epoch::new(5));
|
spec.electra_fork_epoch = Some(Epoch::new(5));
|
||||||
spec.fulu_fork_epoch = Some(Epoch::new(6));
|
spec.fulu_fork_epoch = Some(Epoch::new(6));
|
||||||
|
spec.gloas_fork_epoch = Some(Epoch::new(7));
|
||||||
spec.blob_schedule = BlobSchedule::new(blob_parameters);
|
spec.blob_schedule = BlobSchedule::new(blob_parameters);
|
||||||
spec
|
spec
|
||||||
}
|
}
|
||||||
@@ -194,6 +195,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(context.fork_exists(ForkName::Electra));
|
assert!(context.fork_exists(ForkName::Electra));
|
||||||
assert!(context.fork_exists(ForkName::Fulu));
|
assert!(context.fork_exists(ForkName::Fulu));
|
||||||
|
assert!(context.fork_exists(ForkName::Gloas));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use tree_hash_derive::TreeHash;
|
|||||||
#[cfg_attr(feature = "arbitrary", arbitrary(bound = "E: EthSpec"))]
|
#[cfg_attr(feature = "arbitrary", arbitrary(bound = "E: EthSpec"))]
|
||||||
#[context_deserialize(ForkName)]
|
#[context_deserialize(ForkName)]
|
||||||
pub struct IndexedPayloadAttestation<E: EthSpec> {
|
pub struct IndexedPayloadAttestation<E: EthSpec> {
|
||||||
|
#[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
|
||||||
pub attesting_indices: VariableList<u64, E::PTCSize>,
|
pub attesting_indices: VariableList<u64, E::PTCSize>,
|
||||||
pub data: PayloadAttestationData,
|
pub data: PayloadAttestationData,
|
||||||
pub signature: AggregateSignature,
|
pub signature: AggregateSignature,
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ pub mod pending_deposit;
|
|||||||
pub mod pending_partial_withdrawal;
|
pub mod pending_partial_withdrawal;
|
||||||
pub mod proposer_preparation_data;
|
pub mod proposer_preparation_data;
|
||||||
pub mod proposer_slashing;
|
pub mod proposer_slashing;
|
||||||
|
pub mod ptc;
|
||||||
pub mod relative_epoch;
|
pub mod relative_epoch;
|
||||||
pub mod selection_proof;
|
pub mod selection_proof;
|
||||||
pub mod shuffling_id;
|
pub mod shuffling_id;
|
||||||
@@ -249,6 +250,7 @@ pub use crate::preset::{
|
|||||||
};
|
};
|
||||||
pub use crate::proposer_preparation_data::ProposerPreparationData;
|
pub use crate::proposer_preparation_data::ProposerPreparationData;
|
||||||
pub use crate::proposer_slashing::ProposerSlashing;
|
pub use crate::proposer_slashing::ProposerSlashing;
|
||||||
|
pub use crate::ptc::PTC;
|
||||||
pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch};
|
pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch};
|
||||||
pub use crate::runtime_fixed_vector::RuntimeFixedVector;
|
pub use crate::runtime_fixed_vector::RuntimeFixedVector;
|
||||||
pub use crate::runtime_var_list::RuntimeVariableList;
|
pub use crate::runtime_var_list::RuntimeVariableList;
|
||||||
|
|||||||
57
consensus/types/src/ptc.rs
Normal file
57
consensus/types/src/ptc.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
use crate::*;
|
||||||
|
use safe_arith::SafeArith;
|
||||||
|
|
||||||
|
/// TODO(EIP-7732): is it easier to return u64 or usize?
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct PTC<E: EthSpec>(FixedVector<usize, E::PTCSize>);
|
||||||
|
|
||||||
|
// TODO(EIP-7732): check this implementation against the latest spec
|
||||||
|
// https://ethereum.github.io/consensus-specs/specs/_features/eip7732/beacon-chain/#new-get_ptc
|
||||||
|
impl<E: EthSpec> PTC<E> {
|
||||||
|
pub fn from_committees(committees: &[BeaconCommittee]) -> Result<Self, BeaconStateError> {
|
||||||
|
// this function is only used here and
|
||||||
|
// I have no idea where else to put it
|
||||||
|
fn bit_floor(n: u64) -> u64 {
|
||||||
|
if n == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1 << (n.leading_zeros() as u64 ^ 63)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let committee_count_per_slot = committees.len() as u64;
|
||||||
|
let committees_per_slot = bit_floor(std::cmp::min(
|
||||||
|
committee_count_per_slot,
|
||||||
|
E::PTCSize::to_u64(),
|
||||||
|
)) as usize;
|
||||||
|
let members_per_committee = E::PTCSize::to_usize().safe_div(committees_per_slot)?;
|
||||||
|
|
||||||
|
let mut ptc = Vec::with_capacity(E::PTCSize::to_usize());
|
||||||
|
for idx in 0..committees_per_slot {
|
||||||
|
let beacon_committee = committees
|
||||||
|
.get(idx as usize)
|
||||||
|
.ok_or_else(|| Error::InvalidCommitteeIndex(idx as u64))?;
|
||||||
|
ptc.extend_from_slice(&beacon_committee.committee[..members_per_committee]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self(FixedVector::from(ptc)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, E: EthSpec> IntoIterator for &'a PTC<E> {
|
||||||
|
type Item = &'a usize;
|
||||||
|
type IntoIter = std::slice::Iter<'a, usize>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.0.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> IntoIterator for PTC<E> {
|
||||||
|
type Item = usize;
|
||||||
|
type IntoIter = std::vec::IntoIter<usize>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.0.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,7 +55,36 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo(eip-7732): implement verify_signature since spec calls for verify_execution_payload_envelope_signature
|
/// Verify `self.signature`.
|
||||||
|
///
|
||||||
|
/// The `parent_state` is the post-state of the beacon block with
|
||||||
|
/// block_root = self.message.beacon_block_root
|
||||||
|
pub fn verify_signature(
|
||||||
|
&self,
|
||||||
|
parent_state: &BeaconState<E>,
|
||||||
|
genesis_validators_root: Hash256,
|
||||||
|
spec: &ChainSpec,
|
||||||
|
) -> Result<bool, BeaconStateError> {
|
||||||
|
let domain = spec.get_domain(
|
||||||
|
parent_state.current_epoch(),
|
||||||
|
Domain::BeaconBuilder,
|
||||||
|
&parent_state.fork(),
|
||||||
|
genesis_validators_root,
|
||||||
|
);
|
||||||
|
let pubkey = parent_state
|
||||||
|
.validators()
|
||||||
|
.get(self.message().builder_index() as usize)
|
||||||
|
.and_then(|v| {
|
||||||
|
let pk: Option<PublicKey> = v.pubkey.decompress().ok();
|
||||||
|
pk
|
||||||
|
})
|
||||||
|
.ok_or_else(|| {
|
||||||
|
BeaconStateError::UnknownValidator(self.message().builder_index() as usize)
|
||||||
|
})?;
|
||||||
|
let message = self.message().signing_root(domain);
|
||||||
|
|
||||||
|
Ok(self.signature().verify(&pubkey, message))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for SignedExecutionPayloadEnvelope<E> {
|
impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for SignedExecutionPayloadEnvelope<E> {
|
||||||
|
|||||||
Reference in New Issue
Block a user