mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-05 13:54:36 +00:00
Upgrade to EIP-7732
This commit is contained in:
@@ -144,6 +144,13 @@ where
|
|||||||
List<PendingPartialWithdrawal, E::PendingPartialWithdrawalsLimit>,
|
List<PendingPartialWithdrawal, E::PendingPartialWithdrawalsLimit>,
|
||||||
#[superstruct(only(Electra, EIP7732))]
|
#[superstruct(only(Electra, EIP7732))]
|
||||||
pub pending_consolidations: List<PendingConsolidation, E::PendingConsolidationsLimit>,
|
pub pending_consolidations: List<PendingConsolidation, E::PendingConsolidationsLimit>,
|
||||||
|
|
||||||
|
#[superstruct(only(EIP7732))]
|
||||||
|
pub latest_block_hash: ExecutionBlockHash,
|
||||||
|
#[superstruct(only(EIP7732))]
|
||||||
|
pub latest_full_slot: Slot,
|
||||||
|
#[superstruct(only(EIP7732))]
|
||||||
|
pub latest_withdrawals_root: Hash256,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> PartialBeaconState<E> {
|
impl<E: EthSpec> PartialBeaconState<E> {
|
||||||
@@ -432,7 +439,10 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
|
|||||||
earliest_consolidation_epoch,
|
earliest_consolidation_epoch,
|
||||||
pending_balance_deposits,
|
pending_balance_deposits,
|
||||||
pending_partial_withdrawals,
|
pending_partial_withdrawals,
|
||||||
pending_consolidations
|
pending_consolidations,
|
||||||
|
latest_block_hash,
|
||||||
|
latest_full_slot,
|
||||||
|
latest_withdrawals_root
|
||||||
],
|
],
|
||||||
[historical_summaries]
|
[historical_summaries]
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::common::DepositDataTree;
|
|||||||
use crate::upgrade::electra::upgrade_state_to_electra;
|
use crate::upgrade::electra::upgrade_state_to_electra;
|
||||||
use crate::upgrade::{
|
use crate::upgrade::{
|
||||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||||
|
upgrade_to_eip7732,
|
||||||
};
|
};
|
||||||
use safe_arith::{ArithError, SafeArith};
|
use safe_arith::{ArithError, SafeArith};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -140,6 +141,20 @@ pub fn initialize_beacon_state_from_eth1<E: EthSpec>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upgrade to EIP-7732 if configured from genesis.
|
||||||
|
if spec
|
||||||
|
.eip7732_fork_epoch
|
||||||
|
.map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch())
|
||||||
|
{
|
||||||
|
upgrade_to_eip7732(&mut state, spec)?;
|
||||||
|
|
||||||
|
// Remove intermediate Electra fork from `state.fork`.
|
||||||
|
state.fork_mut().previous_version = spec.eip7732_fork_version;
|
||||||
|
|
||||||
|
// Here's where we *would* clone the header but there is no header here so..
|
||||||
|
// TODO(EIP7732): check this
|
||||||
|
}
|
||||||
|
|
||||||
// Now that we have our validators, initialize the caches (including the committees)
|
// Now that we have our validators, initialize the caches (including the committees)
|
||||||
state.build_caches(spec)?;
|
state.build_caches(spec)?;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::upgrade::{
|
use crate::upgrade::{
|
||||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||||
upgrade_to_electra,
|
upgrade_to_eip7732, upgrade_to_electra,
|
||||||
};
|
};
|
||||||
use crate::{per_epoch_processing::EpochProcessingSummary, *};
|
use crate::{per_epoch_processing::EpochProcessingSummary, *};
|
||||||
use safe_arith::{ArithError, SafeArith};
|
use safe_arith::{ArithError, SafeArith};
|
||||||
@@ -70,6 +70,10 @@ pub fn per_slot_processing<E: EthSpec>(
|
|||||||
if spec.electra_fork_epoch == Some(state.current_epoch()) {
|
if spec.electra_fork_epoch == Some(state.current_epoch()) {
|
||||||
upgrade_to_electra(state, spec)?;
|
upgrade_to_electra(state, spec)?;
|
||||||
}
|
}
|
||||||
|
// EIP-7732.
|
||||||
|
if spec.eip7732_fork_epoch == Some(state.current_epoch()) {
|
||||||
|
upgrade_to_eip7732(state, spec)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Additionally build all caches so that all valid states that are advanced always have
|
// Additionally build all caches so that all valid states that are advanced always have
|
||||||
// committee caches built, and we don't have to worry about initialising them at higher
|
// committee caches built, and we don't have to worry about initialising them at higher
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ pub mod altair;
|
|||||||
pub mod bellatrix;
|
pub mod bellatrix;
|
||||||
pub mod capella;
|
pub mod capella;
|
||||||
pub mod deneb;
|
pub mod deneb;
|
||||||
|
pub mod eip7732;
|
||||||
pub mod electra;
|
pub mod electra;
|
||||||
|
|
||||||
pub use altair::upgrade_to_altair;
|
pub use altair::upgrade_to_altair;
|
||||||
pub use bellatrix::upgrade_to_bellatrix;
|
pub use bellatrix::upgrade_to_bellatrix;
|
||||||
pub use capella::upgrade_to_capella;
|
pub use capella::upgrade_to_capella;
|
||||||
pub use deneb::upgrade_to_deneb;
|
pub use deneb::upgrade_to_deneb;
|
||||||
|
pub use eip7732::upgrade_to_eip7732;
|
||||||
pub use electra::upgrade_to_electra;
|
pub use electra::upgrade_to_electra;
|
||||||
|
|||||||
96
consensus/state_processing/src/upgrade/eip7732.rs
Normal file
96
consensus/state_processing/src/upgrade/eip7732.rs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
use bls::Hash256;
|
||||||
|
use std::mem;
|
||||||
|
use types::{
|
||||||
|
BeaconState, BeaconStateEIP7732, BeaconStateError as Error, ChainSpec, EpochCache, EthSpec,
|
||||||
|
ExecutionBid, Fork,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Transform an `Electra` state into an `EIP-7732` state.
|
||||||
|
pub fn upgrade_to_eip7732<E: EthSpec>(
|
||||||
|
pre_state: &mut BeaconState<E>,
|
||||||
|
spec: &ChainSpec,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let epoch = pre_state.current_epoch();
|
||||||
|
let pre = pre_state.as_electra_mut()?;
|
||||||
|
|
||||||
|
let previous_fork_version = pre.fork.current_version;
|
||||||
|
|
||||||
|
// Where possible, use something like `mem::take` to move fields from behind the &mut
|
||||||
|
// reference. For other fields that don't have a good default value, use `clone`.
|
||||||
|
//
|
||||||
|
// Fixed size vectors get cloned because replacing them would require the same size
|
||||||
|
// allocation as cloning.
|
||||||
|
let post = BeaconState::EIP7732(BeaconStateEIP7732 {
|
||||||
|
// Versioning
|
||||||
|
genesis_time: pre.genesis_time,
|
||||||
|
genesis_validators_root: pre.genesis_validators_root,
|
||||||
|
slot: pre.slot,
|
||||||
|
fork: Fork {
|
||||||
|
previous_version: previous_fork_version,
|
||||||
|
current_version: spec.eip7732_fork_version,
|
||||||
|
epoch,
|
||||||
|
},
|
||||||
|
// History
|
||||||
|
latest_block_header: pre.latest_block_header.clone(),
|
||||||
|
block_roots: pre.block_roots.clone(),
|
||||||
|
state_roots: pre.state_roots.clone(),
|
||||||
|
historical_roots: mem::take(&mut pre.historical_roots),
|
||||||
|
// Eth1
|
||||||
|
eth1_data: pre.eth1_data.clone(),
|
||||||
|
eth1_data_votes: mem::take(&mut pre.eth1_data_votes),
|
||||||
|
eth1_deposit_index: pre.eth1_deposit_index,
|
||||||
|
// Registry
|
||||||
|
validators: mem::take(&mut pre.validators),
|
||||||
|
balances: mem::take(&mut pre.balances),
|
||||||
|
// Randomness
|
||||||
|
randao_mixes: pre.randao_mixes.clone(),
|
||||||
|
// Slashings
|
||||||
|
slashings: pre.slashings.clone(),
|
||||||
|
// `Participation
|
||||||
|
previous_epoch_participation: mem::take(&mut pre.previous_epoch_participation),
|
||||||
|
current_epoch_participation: mem::take(&mut pre.current_epoch_participation),
|
||||||
|
// Finality
|
||||||
|
justification_bits: pre.justification_bits.clone(),
|
||||||
|
previous_justified_checkpoint: pre.previous_justified_checkpoint,
|
||||||
|
current_justified_checkpoint: pre.current_justified_checkpoint,
|
||||||
|
finalized_checkpoint: pre.finalized_checkpoint,
|
||||||
|
// Inactivity
|
||||||
|
inactivity_scores: mem::take(&mut pre.inactivity_scores),
|
||||||
|
// Sync committees
|
||||||
|
current_sync_committee: pre.current_sync_committee.clone(),
|
||||||
|
next_sync_committee: pre.next_sync_committee.clone(),
|
||||||
|
// Execution Bid
|
||||||
|
latest_execution_bid: ExecutionBid::default(),
|
||||||
|
// Capella
|
||||||
|
next_withdrawal_index: pre.next_withdrawal_index,
|
||||||
|
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
|
||||||
|
historical_summaries: pre.historical_summaries.clone(),
|
||||||
|
// Deneb
|
||||||
|
// Electra
|
||||||
|
deposit_requests_start_index: pre.deposit_requests_start_index,
|
||||||
|
deposit_balance_to_consume: pre.deposit_balance_to_consume,
|
||||||
|
exit_balance_to_consume: pre.exit_balance_to_consume,
|
||||||
|
earliest_exit_epoch: pre.earliest_exit_epoch,
|
||||||
|
consolidation_balance_to_consume: pre.consolidation_balance_to_consume,
|
||||||
|
earliest_consolidation_epoch: pre.earliest_consolidation_epoch,
|
||||||
|
pending_balance_deposits: mem::take(&mut pre.pending_balance_deposits),
|
||||||
|
pending_partial_withdrawals: mem::take(&mut pre.pending_partial_withdrawals),
|
||||||
|
pending_consolidations: mem::take(&mut pre.pending_consolidations),
|
||||||
|
// EIP-7732
|
||||||
|
latest_block_hash: pre.latest_execution_payload_header.block_hash,
|
||||||
|
latest_full_slot: pre.slot,
|
||||||
|
latest_withdrawals_root: Hash256::default(),
|
||||||
|
// Caches
|
||||||
|
total_active_balance: pre.total_active_balance,
|
||||||
|
progressive_balances_cache: mem::take(&mut pre.progressive_balances_cache),
|
||||||
|
committee_caches: mem::take(&mut pre.committee_caches),
|
||||||
|
pubkey_cache: mem::take(&mut pre.pubkey_cache),
|
||||||
|
exit_cache: mem::take(&mut pre.exit_cache),
|
||||||
|
slashings_cache: mem::take(&mut pre.slashings_cache),
|
||||||
|
epoch_cache: EpochCache::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
*pre_state = post;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -734,6 +734,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockEIP7732<E, Payload>
|
|||||||
deposits: base_block.body.deposits,
|
deposits: base_block.body.deposits,
|
||||||
voluntary_exits: base_block.body.voluntary_exits,
|
voluntary_exits: base_block.body.voluntary_exits,
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
|
signed_execution_bid: SignedExecutionBid::empty(),
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
randao_reveal: Signature::empty(),
|
randao_reveal: Signature::empty(),
|
||||||
eth1_data: Eth1Data {
|
eth1_data: Eth1Data {
|
||||||
@@ -802,6 +803,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> EmptyBlock for BeaconBlockEIP7
|
|||||||
voluntary_exits: VariableList::empty(),
|
voluntary_exits: VariableList::empty(),
|
||||||
sync_aggregate: SyncAggregate::empty(),
|
sync_aggregate: SyncAggregate::empty(),
|
||||||
bls_to_execution_changes: VariableList::empty(),
|
bls_to_execution_changes: VariableList::empty(),
|
||||||
|
signed_execution_bid: SignedExecutionBid::empty(),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ pub struct BeaconBlockBody<E: EthSpec, Payload: AbstractExecPayload<E> = FullPay
|
|||||||
pub blob_kzg_commitments: KzgCommitments<E>,
|
pub blob_kzg_commitments: KzgCommitments<E>,
|
||||||
#[superstruct(only(Electra))]
|
#[superstruct(only(Electra))]
|
||||||
pub execution_requests: ExecutionRequests<E>,
|
pub execution_requests: ExecutionRequests<E>,
|
||||||
|
#[superstruct(only(EIP7732))]
|
||||||
|
pub signed_execution_bid: SignedExecutionBid,
|
||||||
#[superstruct(only(Base, Altair, EIP7732))]
|
#[superstruct(only(Base, Altair, EIP7732))]
|
||||||
#[metastruct(exclude_from(fields))]
|
#[metastruct(exclude_from(fields))]
|
||||||
#[ssz(skip_serializing, skip_deserializing)]
|
#[ssz(skip_serializing, skip_deserializing)]
|
||||||
@@ -745,6 +747,7 @@ impl<E: EthSpec> From<BeaconBlockBodyEIP7732<E, BlindedPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
|
signed_execution_bid,
|
||||||
_phantom,
|
_phantom,
|
||||||
} = body;
|
} = body;
|
||||||
|
|
||||||
@@ -759,6 +762,7 @@ impl<E: EthSpec> From<BeaconBlockBodyEIP7732<E, BlindedPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
|
signed_execution_bid,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -782,6 +786,7 @@ impl<E: EthSpec> From<BeaconBlockBodyEIP7732<E, FullPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
|
signed_execution_bid,
|
||||||
_phantom,
|
_phantom,
|
||||||
} = body;
|
} = body;
|
||||||
|
|
||||||
@@ -797,6 +802,7 @@ impl<E: EthSpec> From<BeaconBlockBodyEIP7732<E, FullPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
|
signed_execution_bid,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -537,6 +537,17 @@ where
|
|||||||
#[superstruct(only(Electra, EIP7732))]
|
#[superstruct(only(Electra, EIP7732))]
|
||||||
pub pending_consolidations: List<PendingConsolidation, E::PendingConsolidationsLimit>,
|
pub pending_consolidations: List<PendingConsolidation, E::PendingConsolidationsLimit>,
|
||||||
|
|
||||||
|
// EIP-7732
|
||||||
|
#[superstruct(only(EIP7732), partial_getter(copy))]
|
||||||
|
#[metastruct(exclude_from(tree_lists))]
|
||||||
|
pub latest_block_hash: ExecutionBlockHash,
|
||||||
|
#[superstruct(only(EIP7732), partial_getter(copy))]
|
||||||
|
#[metastruct(exclude_from(tree_lists))]
|
||||||
|
pub latest_full_slot: Slot,
|
||||||
|
#[superstruct(only(EIP7732), partial_getter(copy))]
|
||||||
|
#[metastruct(exclude_from(tree_lists))]
|
||||||
|
pub latest_withdrawals_root: Hash256,
|
||||||
|
|
||||||
// Caching (not in the spec)
|
// Caching (not in the spec)
|
||||||
#[serde(skip_serializing, skip_deserializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
#[ssz(skip_serializing, skip_deserializing)]
|
#[ssz(skip_serializing, skip_deserializing)]
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use tree_hash_derive::TreeHash;
|
|||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
arbitrary::Arbitrary,
|
arbitrary::Arbitrary,
|
||||||
|
Default,
|
||||||
Debug,
|
Debug,
|
||||||
Clone,
|
Clone,
|
||||||
PartialEq,
|
|
||||||
Serialize,
|
Serialize,
|
||||||
Encode,
|
Encode,
|
||||||
Decode,
|
Decode,
|
||||||
@@ -18,6 +18,7 @@ use tree_hash_derive::TreeHash;
|
|||||||
Derivative,
|
Derivative,
|
||||||
TestRandom,
|
TestRandom,
|
||||||
)]
|
)]
|
||||||
|
#[derivative(PartialEq, Hash)]
|
||||||
// This is what Potuz' spec calls an `ExecutionPayload` even though it's clearly a bid.
|
// This is what Potuz' spec calls an `ExecutionPayload` even though it's clearly a bid.
|
||||||
pub struct ExecutionBid {
|
pub struct ExecutionBid {
|
||||||
parent_block_hash: ExecutionBlockHash,
|
parent_block_hash: ExecutionBlockHash,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::test_utils::TestRandom;
|
use crate::test_utils::TestRandom;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use derivative::Derivative;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
use test_random_derive::TestRandom;
|
use test_random_derive::TestRandom;
|
||||||
@@ -11,17 +12,27 @@ use tree_hash_derive::TreeHash;
|
|||||||
TreeHash,
|
TreeHash,
|
||||||
Debug,
|
Debug,
|
||||||
Clone,
|
Clone,
|
||||||
PartialEq,
|
|
||||||
Encode,
|
Encode,
|
||||||
Decode,
|
Decode,
|
||||||
Serialize,
|
Serialize,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
|
Derivative,
|
||||||
)]
|
)]
|
||||||
|
#[derivative(PartialEq, Hash)]
|
||||||
pub struct SignedExecutionBid {
|
pub struct SignedExecutionBid {
|
||||||
pub message: ExecutionBid,
|
pub message: ExecutionBid,
|
||||||
pub signature: Signature,
|
pub signature: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SignedExecutionBid {
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self {
|
||||||
|
message: ExecutionBid::default(),
|
||||||
|
signature: Signature::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::decode::{ssz_decode_state, yaml_decode_file};
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use state_processing::upgrade::{
|
use state_processing::upgrade::{
|
||||||
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb,
|
||||||
upgrade_to_electra,
|
upgrade_to_eip7732, upgrade_to_electra,
|
||||||
};
|
};
|
||||||
use types::BeaconState;
|
use types::BeaconState;
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ impl<E: EthSpec> Case for ForkTest<E> {
|
|||||||
ForkName::Capella => upgrade_to_capella(&mut result_state, spec).map(|_| result_state),
|
ForkName::Capella => upgrade_to_capella(&mut result_state, spec).map(|_| result_state),
|
||||||
ForkName::Deneb => upgrade_to_deneb(&mut result_state, spec).map(|_| result_state),
|
ForkName::Deneb => upgrade_to_deneb(&mut result_state, spec).map(|_| result_state),
|
||||||
ForkName::Electra => upgrade_to_electra(&mut result_state, spec).map(|_| result_state),
|
ForkName::Electra => upgrade_to_electra(&mut result_state, spec).map(|_| result_state),
|
||||||
ForkName::EIP7732 => todo!("upgrade_to_eip7732 not yet implemented"),
|
ForkName::EIP7732 => upgrade_to_eip7732(&mut result_state, spec).map(|_| result_state),
|
||||||
};
|
};
|
||||||
|
|
||||||
compare_beacon_state_results_without_caches(&mut result, &mut expected)
|
compare_beacon_state_results_without_caches(&mut result, &mut expected)
|
||||||
|
|||||||
Reference in New Issue
Block a user