mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 11:41:51 +00:00
Add Altair tests to op pool (#2723)
## Issue Addressed NA ## Proposed Changes Adds some more testing for Altair to the op pool. Credits to @michaelsproul for some appropriated efforts here. ## Additional Info NA Co-authored-by: Michael Sproul <michael@sigmaprime.io>
This commit is contained in:
@@ -12,9 +12,9 @@ use types::{
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AttMaxCover<'a, T: EthSpec> {
|
||||
/// Underlying attestation.
|
||||
att: &'a Attestation<T>,
|
||||
pub att: &'a Attestation<T>,
|
||||
/// Mapping of validator indices and their rewards.
|
||||
fresh_validators_rewards: HashMap<u64, u64>,
|
||||
pub fresh_validators_rewards: HashMap<u64, u64>,
|
||||
}
|
||||
|
||||
impl<'a, T: EthSpec> AttMaxCover<'a, T> {
|
||||
|
||||
@@ -354,10 +354,15 @@ impl<T: EthSpec> OperationPool<T> {
|
||||
/// This function computes both types of slashings together, because
|
||||
/// attester slashings may be invalidated by proposer slashings included
|
||||
/// earlier in the block.
|
||||
pub fn get_slashings(
|
||||
pub fn get_slashings_and_exits(
|
||||
&self,
|
||||
state: &BeaconState<T>,
|
||||
) -> (Vec<ProposerSlashing>, Vec<AttesterSlashing<T>>) {
|
||||
spec: &ChainSpec,
|
||||
) -> (
|
||||
Vec<ProposerSlashing>,
|
||||
Vec<AttesterSlashing<T>>,
|
||||
Vec<SignedVoluntaryExit>,
|
||||
) {
|
||||
let proposer_slashings = filter_limit_operations(
|
||||
self.proposer_slashings.read().values(),
|
||||
|slashing| {
|
||||
@@ -371,7 +376,7 @@ impl<T: EthSpec> OperationPool<T> {
|
||||
|
||||
// Set of validators to be slashed, so we don't attempt to construct invalid attester
|
||||
// slashings.
|
||||
let to_be_slashed = proposer_slashings
|
||||
let mut to_be_slashed = proposer_slashings
|
||||
.iter()
|
||||
.map(|s| s.signed_header_1.message.proposer_index)
|
||||
.collect::<HashSet<_>>();
|
||||
@@ -391,10 +396,19 @@ impl<T: EthSpec> OperationPool<T> {
|
||||
T::MaxAttesterSlashings::to_usize(),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|cover| cover.object().clone())
|
||||
.map(|cover| {
|
||||
to_be_slashed.extend(cover.covering_set().keys());
|
||||
cover.object().clone()
|
||||
})
|
||||
.collect();
|
||||
|
||||
(proposer_slashings, attester_slashings)
|
||||
let voluntary_exits = self.get_voluntary_exits(
|
||||
state,
|
||||
|exit| !to_be_slashed.contains(&exit.message.validator_index),
|
||||
spec,
|
||||
);
|
||||
|
||||
(proposer_slashings, attester_slashings, voluntary_exits)
|
||||
}
|
||||
|
||||
/// Prune proposer slashings for validators which are exited in the finalized epoch.
|
||||
@@ -454,14 +468,18 @@ impl<T: EthSpec> OperationPool<T> {
|
||||
}
|
||||
|
||||
/// Get a list of voluntary exits for inclusion in a block.
|
||||
pub fn get_voluntary_exits(
|
||||
fn get_voluntary_exits<F>(
|
||||
&self,
|
||||
state: &BeaconState<T>,
|
||||
filter: F,
|
||||
spec: &ChainSpec,
|
||||
) -> Vec<SignedVoluntaryExit> {
|
||||
) -> Vec<SignedVoluntaryExit>
|
||||
where
|
||||
F: Fn(&SignedVoluntaryExit) -> bool,
|
||||
{
|
||||
filter_limit_operations(
|
||||
self.voluntary_exits.read().values(),
|
||||
|exit| verify_exit(state, exit, VerifySignatures::False, spec).is_ok(),
|
||||
|exit| filter(exit) && verify_exit(state, exit, VerifySignatures::False, spec).is_ok(),
|
||||
T::MaxVoluntaryExits::to_usize(),
|
||||
)
|
||||
}
|
||||
@@ -609,15 +627,11 @@ mod release_tests {
|
||||
use super::attestation::earliest_attestation_validators;
|
||||
use super::*;
|
||||
use beacon_chain::test_utils::{
|
||||
BeaconChainHarness, EphemeralHarnessType, RelativeSyncCommittee,
|
||||
test_spec, BeaconChainHarness, EphemeralHarnessType, RelativeSyncCommittee,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use state_processing::{
|
||||
common::{base::get_base_reward, get_attesting_indices},
|
||||
VerifyOperation,
|
||||
};
|
||||
use state_processing::VerifyOperation;
|
||||
use std::collections::BTreeSet;
|
||||
use std::iter::FromIterator;
|
||||
use types::consts::altair::SYNC_COMMITTEE_SUBNET_COUNT;
|
||||
use types::*;
|
||||
|
||||
@@ -647,11 +661,11 @@ mod release_tests {
|
||||
fn attestation_test_state<E: EthSpec>(
|
||||
num_committees: usize,
|
||||
) -> (BeaconChainHarness<EphemeralHarnessType<E>>, ChainSpec) {
|
||||
let spec = E::default_spec();
|
||||
let spec = test_spec::<E>();
|
||||
|
||||
let num_validators =
|
||||
num_committees * E::slots_per_epoch() as usize * spec.target_committee_size;
|
||||
let harness = get_harness::<E>(num_validators, None);
|
||||
let harness = get_harness::<E>(num_validators, Some(spec.clone()));
|
||||
|
||||
(harness, spec)
|
||||
}
|
||||
@@ -682,6 +696,12 @@ mod release_tests {
|
||||
#[test]
|
||||
fn test_earliest_attestation() {
|
||||
let (harness, ref spec) = attestation_test_state::<MainnetEthSpec>(1);
|
||||
|
||||
// Only run this test on the phase0 hard-fork.
|
||||
if spec.altair_fork_epoch != None {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut state = harness.get_current_state();
|
||||
let slot = state.slot();
|
||||
let committees = state
|
||||
@@ -725,7 +745,6 @@ mod release_tests {
|
||||
.num_set_bits()
|
||||
);
|
||||
|
||||
// FIXME(altair): handle altair in these tests
|
||||
state
|
||||
.as_base_mut()
|
||||
.unwrap()
|
||||
@@ -1146,46 +1165,25 @@ mod release_tests {
|
||||
let total_active_balance = state.get_total_active_balance().unwrap();
|
||||
|
||||
// Set of indices covered by previous attestations in `best_attestations`.
|
||||
let mut seen_indices = BTreeSet::new();
|
||||
let mut seen_indices = BTreeSet::<u64>::new();
|
||||
// Used for asserting that rewards are in decreasing order.
|
||||
let mut prev_reward = u64::max_value();
|
||||
|
||||
for att in &best_attestations {
|
||||
let fresh_validators_bitlist =
|
||||
earliest_attestation_validators(att, &state, state.as_base().unwrap());
|
||||
let committee = state
|
||||
.get_beacon_committee(att.data.slot, att.data.index)
|
||||
.expect("should get beacon committee");
|
||||
|
||||
let att_indices = BTreeSet::from_iter(
|
||||
get_attesting_indices::<MainnetEthSpec>(
|
||||
committee.committee,
|
||||
&fresh_validators_bitlist,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let fresh_indices = &att_indices - &seen_indices;
|
||||
|
||||
let rewards = fresh_indices
|
||||
.iter()
|
||||
.map(|validator_index| {
|
||||
get_base_reward(
|
||||
&state,
|
||||
*validator_index as usize,
|
||||
total_active_balance,
|
||||
spec,
|
||||
)
|
||||
let mut fresh_validators_rewards =
|
||||
AttMaxCover::new(att, &state, total_active_balance, spec)
|
||||
.unwrap()
|
||||
/ spec.proposer_reward_quotient
|
||||
})
|
||||
.sum();
|
||||
.fresh_validators_rewards;
|
||||
|
||||
// Remove validators covered by previous attestations.
|
||||
fresh_validators_rewards
|
||||
.retain(|validator_index, _| !seen_indices.contains(validator_index));
|
||||
|
||||
// Check that rewards are in decreasing order
|
||||
let rewards = fresh_validators_rewards.values().sum();
|
||||
assert!(prev_reward >= rewards);
|
||||
|
||||
prev_reward = rewards;
|
||||
seen_indices.extend(fresh_indices);
|
||||
seen_indices.extend(fresh_validators_rewards.keys());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1211,7 +1209,10 @@ mod release_tests {
|
||||
.insert_proposer_slashing(slashing2.clone().validate(&state, &harness.spec).unwrap());
|
||||
|
||||
// Should only get the second slashing back.
|
||||
assert_eq!(op_pool.get_slashings(&state).0, vec![slashing2]);
|
||||
assert_eq!(
|
||||
op_pool.get_slashings_and_exits(&state, &harness.spec).0,
|
||||
vec![slashing2]
|
||||
);
|
||||
}
|
||||
|
||||
// Sanity check on the pruning of proposer slashings
|
||||
@@ -1224,7 +1225,10 @@ mod release_tests {
|
||||
let slashing = harness.make_proposer_slashing(0);
|
||||
op_pool.insert_proposer_slashing(slashing.clone().validate(&state, &harness.spec).unwrap());
|
||||
op_pool.prune_proposer_slashings(&state);
|
||||
assert_eq!(op_pool.get_slashings(&state).0, vec![slashing]);
|
||||
assert_eq!(
|
||||
op_pool.get_slashings_and_exits(&state, &harness.spec).0,
|
||||
vec![slashing]
|
||||
);
|
||||
}
|
||||
|
||||
// Sanity check on the pruning of attester slashings
|
||||
@@ -1241,7 +1245,10 @@ mod release_tests {
|
||||
state.fork(),
|
||||
);
|
||||
op_pool.prune_attester_slashings(&state);
|
||||
assert_eq!(op_pool.get_slashings(&state).1, vec![slashing]);
|
||||
assert_eq!(
|
||||
op_pool.get_slashings_and_exits(&state, &harness.spec).1,
|
||||
vec![slashing]
|
||||
);
|
||||
}
|
||||
|
||||
// Check that we get maximum coverage for attester slashings (highest qty of validators slashed)
|
||||
@@ -1274,7 +1281,7 @@ mod release_tests {
|
||||
state.fork(),
|
||||
);
|
||||
|
||||
let best_slashings = op_pool.get_slashings(&state);
|
||||
let best_slashings = op_pool.get_slashings_and_exits(&state, &harness.spec);
|
||||
assert_eq!(best_slashings.1, vec![slashing_4, slashing_3]);
|
||||
}
|
||||
|
||||
@@ -1308,7 +1315,7 @@ mod release_tests {
|
||||
state.fork(),
|
||||
);
|
||||
|
||||
let best_slashings = op_pool.get_slashings(&state);
|
||||
let best_slashings = op_pool.get_slashings_and_exits(&state, &harness.spec);
|
||||
assert_eq!(best_slashings.1, vec![slashing_1, slashing_3]);
|
||||
}
|
||||
|
||||
@@ -1339,7 +1346,7 @@ mod release_tests {
|
||||
state.fork(),
|
||||
);
|
||||
|
||||
let best_slashings = op_pool.get_slashings(&state);
|
||||
let best_slashings = op_pool.get_slashings_and_exits(&state, &harness.spec);
|
||||
assert_eq!(best_slashings.1, vec![a_slashing_1, a_slashing_3]);
|
||||
}
|
||||
|
||||
@@ -1371,11 +1378,11 @@ mod release_tests {
|
||||
state.fork(),
|
||||
);
|
||||
|
||||
let best_slashings = op_pool.get_slashings(&state);
|
||||
let best_slashings = op_pool.get_slashings_and_exits(&state, &harness.spec);
|
||||
assert_eq!(best_slashings.1, vec![slashing_1, slashing_3]);
|
||||
}
|
||||
|
||||
//Max coverage should be affected by the overall effective balances
|
||||
// Max coverage should be affected by the overall effective balances
|
||||
#[test]
|
||||
fn max_coverage_effective_balances() {
|
||||
let harness = get_harness(32, None);
|
||||
@@ -1403,7 +1410,7 @@ mod release_tests {
|
||||
state.fork(),
|
||||
);
|
||||
|
||||
let best_slashings = op_pool.get_slashings(&state);
|
||||
let best_slashings = op_pool.get_slashings_and_exits(&state, &harness.spec);
|
||||
assert_eq!(best_slashings.1, vec![slashing_2, slashing_3]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user