mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -17,12 +17,13 @@ use fork_choice::{
|
||||
use store::MemoryStore;
|
||||
use types::{
|
||||
test_utils::generate_deterministic_keypair, BeaconBlockRef, BeaconState, ChainSpec, Checkpoint,
|
||||
Epoch, EthSpec, Hash256, IndexedAttestation, MainnetEthSpec, SignedBeaconBlock, Slot, SubnetId,
|
||||
Epoch, EthSpec, ForkName, Hash256, IndexedAttestation, MainnetEthSpec, ProgressiveBalancesMode,
|
||||
RelativeEpoch, SignedBeaconBlock, Slot, SubnetId,
|
||||
};
|
||||
|
||||
pub type E = MainnetEthSpec;
|
||||
|
||||
pub const VALIDATOR_COUNT: usize = 32;
|
||||
pub const VALIDATOR_COUNT: usize = 64;
|
||||
|
||||
/// Defines some delay between when an attestation is created and when it is mutated.
|
||||
pub enum MutationDelay {
|
||||
@@ -68,6 +69,24 @@ impl ForkChoiceTest {
|
||||
Self { harness }
|
||||
}
|
||||
|
||||
/// Creates a new tester with the specified `ProgressiveBalancesMode` and genesis from latest fork.
|
||||
fn new_with_progressive_balances_mode(mode: ProgressiveBalancesMode) -> ForkChoiceTest {
|
||||
// genesis with latest fork (at least altair required to test the cache)
|
||||
let spec = ForkName::latest().make_genesis_spec(ChainSpec::default());
|
||||
let harness = BeaconChainHarness::builder(MainnetEthSpec)
|
||||
.spec(spec)
|
||||
.chain_config(ChainConfig {
|
||||
progressive_balances_mode: mode,
|
||||
..ChainConfig::default()
|
||||
})
|
||||
.deterministic_keypairs(VALIDATOR_COUNT)
|
||||
.fresh_ephemeral_store()
|
||||
.mock_execution_layer()
|
||||
.build();
|
||||
|
||||
Self { harness }
|
||||
}
|
||||
|
||||
/// Get a value from the `ForkChoice` instantiation.
|
||||
fn get<T, U>(&self, func: T) -> U
|
||||
where
|
||||
@@ -212,6 +231,39 @@ impl ForkChoiceTest {
|
||||
self
|
||||
}
|
||||
|
||||
/// Slash a validator from the previous epoch committee.
|
||||
pub async fn add_previous_epoch_attester_slashing(self) -> Self {
|
||||
let state = self.harness.get_current_state();
|
||||
let previous_epoch_shuffling = state.get_shuffling(RelativeEpoch::Previous).unwrap();
|
||||
let validator_indices = previous_epoch_shuffling
|
||||
.iter()
|
||||
.map(|idx| *idx as u64)
|
||||
.take(1)
|
||||
.collect();
|
||||
|
||||
self.harness
|
||||
.add_attester_slashing(validator_indices)
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Slash the proposer of a block in the previous epoch.
|
||||
pub async fn add_previous_epoch_proposer_slashing(self, slots_per_epoch: u64) -> Self {
|
||||
let previous_epoch_slot = self.harness.get_current_slot() - slots_per_epoch;
|
||||
let previous_epoch_block = self
|
||||
.harness
|
||||
.chain
|
||||
.block_at_slot(previous_epoch_slot, WhenSlotSkipped::None)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let proposer_index: u64 = previous_epoch_block.message().proposer_index();
|
||||
|
||||
self.harness.add_proposer_slashing(proposer_index).unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Apply `count` blocks to the chain (without attestations).
|
||||
pub async fn apply_blocks_without_new_attestations(self, count: usize) -> Self {
|
||||
self.harness.advance_slot();
|
||||
@@ -286,7 +338,9 @@ impl ForkChoiceTest {
|
||||
Duration::from_secs(0),
|
||||
&state,
|
||||
PayloadVerificationStatus::Verified,
|
||||
self.harness.chain.config.progressive_balances_mode,
|
||||
&self.harness.chain.spec,
|
||||
self.harness.logger(),
|
||||
)
|
||||
.unwrap();
|
||||
self
|
||||
@@ -328,7 +382,9 @@ impl ForkChoiceTest {
|
||||
Duration::from_secs(0),
|
||||
&state,
|
||||
PayloadVerificationStatus::Verified,
|
||||
self.harness.chain.config.progressive_balances_mode,
|
||||
&self.harness.chain.spec,
|
||||
self.harness.logger(),
|
||||
)
|
||||
.err()
|
||||
.expect("on_block did not return an error");
|
||||
@@ -1287,3 +1343,49 @@ async fn weak_subjectivity_check_epoch_boundary_is_skip_slot_failure() {
|
||||
.assert_finalized_epoch_is_less_than(checkpoint.epoch)
|
||||
.assert_shutdown_signal_sent();
|
||||
}
|
||||
|
||||
/// Checks that `ProgressiveBalancesCache` is updated correctly after an attester slashing event,
|
||||
/// where the slashed validator is a target attester in previous / current epoch.
|
||||
#[tokio::test]
|
||||
async fn progressive_balances_cache_attester_slashing() {
|
||||
ForkChoiceTest::new_with_progressive_balances_mode(ProgressiveBalancesMode::Strict)
|
||||
// first two epochs
|
||||
.apply_blocks_while(|_, state| state.finalized_checkpoint().epoch == 0)
|
||||
.await
|
||||
.unwrap()
|
||||
.add_previous_epoch_attester_slashing()
|
||||
.await
|
||||
// expect fork choice to import blocks successfully after a previous epoch attester is
|
||||
// slashed, i.e. the slashed attester's balance is correctly excluded from
|
||||
// the previous epoch total balance in `ProgressiveBalancesCache`.
|
||||
.apply_blocks(1)
|
||||
.await
|
||||
// expect fork choice to import another epoch of blocks successfully - the slashed
|
||||
// attester's balance should be excluded from the current epoch total balance in
|
||||
// `ProgressiveBalancesCache` as well.
|
||||
.apply_blocks(MainnetEthSpec::slots_per_epoch() as usize)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Checks that `ProgressiveBalancesCache` is updated correctly after a proposer slashing event,
|
||||
/// where the slashed validator is a target attester in previous / current epoch.
|
||||
#[tokio::test]
|
||||
async fn progressive_balances_cache_proposer_slashing() {
|
||||
ForkChoiceTest::new_with_progressive_balances_mode(ProgressiveBalancesMode::Strict)
|
||||
// first two epochs
|
||||
.apply_blocks_while(|_, state| state.finalized_checkpoint().epoch == 0)
|
||||
.await
|
||||
.unwrap()
|
||||
.add_previous_epoch_proposer_slashing(MainnetEthSpec::slots_per_epoch())
|
||||
.await
|
||||
// expect fork choice to import blocks successfully after a previous epoch proposer is
|
||||
// slashed, i.e. the slashed proposer's balance is correctly excluded from
|
||||
// the previous epoch total balance in `ProgressiveBalancesCache`.
|
||||
.apply_blocks(1)
|
||||
.await
|
||||
// expect fork choice to import another epoch of blocks successfully - the slashed
|
||||
// proposer's balance should be excluded from the current epoch total balance in
|
||||
// `ProgressiveBalancesCache` as well.
|
||||
.apply_blocks(MainnetEthSpec::slots_per_epoch() as usize)
|
||||
.await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user