superstruct the AttesterSlashing (#5636)

* `superstruct` Attester Fork Variants

* Push a little further

* Deal with Encode / Decode of AttesterSlashing

* not so sure about this..

* Stop Encode/Decode Bounds from Propagating Out

* Tons of Changes..

* More Conversions to AttestationRef

* Add AsReference trait (#15)

* Add AsReference trait

* Fix some snafus

* Got it Compiling! :D

* Got Tests Building

* Get beacon chain tests compiling

---------

Co-authored-by: Michael Sproul <micsproul@gmail.com>
This commit is contained in:
ethDreamer
2024-05-02 18:00:21 -05:00
committed by GitHub
parent 3b7132bc0d
commit e6c7f145dd
53 changed files with 1405 additions and 437 deletions

View File

@@ -2,8 +2,9 @@ use crate::AttestationStats;
use itertools::Itertools;
use std::collections::HashMap;
use types::{
attestation::{AttestationBase, AttestationElectra}, superstruct, AggregateSignature, Attestation, AttestationData,
BeaconState, BitList, BitVector, Checkpoint, Epoch, EthSpec, Hash256, Slot,
attestation::{AttestationBase, AttestationElectra},
superstruct, AggregateSignature, Attestation, AttestationData, BeaconState, BitList, BitVector,
Checkpoint, Epoch, EthSpec, Hash256, Slot,
};
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
@@ -121,12 +122,14 @@ impl<'a, E: EthSpec> AttestationRef<'a, E> {
data: self.attestation_data(),
signature: indexed_att.signature.clone(),
}),
CompactIndexedAttestation::Electra(indexed_att) => Attestation::Electra(AttestationElectra {
aggregation_bits: indexed_att.aggregation_bits.clone(),
data: self.attestation_data(),
signature: indexed_att.signature.clone(),
committee_bits: indexed_att.committee_bits.clone(),
}),
CompactIndexedAttestation::Electra(indexed_att) => {
Attestation::Electra(AttestationElectra {
aggregation_bits: indexed_att.aggregation_bits.clone(),
data: self.attestation_data(),
signature: indexed_att.signature.clone(),
committee_bits: indexed_att.committee_bits.clone(),
})
}
}
}
}

View File

@@ -1,17 +1,17 @@
use crate::max_cover::MaxCover;
use state_processing::per_block_processing::get_slashable_indices_modular;
use std::collections::{HashMap, HashSet};
use types::{AttesterSlashing, BeaconState, EthSpec};
use types::{AttesterSlashing, AttesterSlashingRef, BeaconState, EthSpec};
#[derive(Debug, Clone)]
pub struct AttesterSlashingMaxCover<'a, E: EthSpec> {
slashing: &'a AttesterSlashing<E>,
slashing: AttesterSlashingRef<'a, E>,
effective_balances: HashMap<u64, u64>,
}
impl<'a, E: EthSpec> AttesterSlashingMaxCover<'a, E> {
pub fn new(
slashing: &'a AttesterSlashing<E>,
slashing: AttesterSlashingRef<'a, E>,
proposer_slashing_indices: &HashSet<u64>,
state: &BeaconState<E>,
) -> Option<Self> {
@@ -39,16 +39,16 @@ impl<'a, E: EthSpec> AttesterSlashingMaxCover<'a, E> {
impl<'a, E: EthSpec> MaxCover for AttesterSlashingMaxCover<'a, E> {
/// The result type, of which we would eventually like a collection of maximal quality.
type Object = AttesterSlashing<E>;
type Intermediate = AttesterSlashing<E>;
type Intermediate = AttesterSlashingRef<'a, E>;
/// The type used to represent sets.
type Set = HashMap<u64, u64>;
fn intermediate(&self) -> &AttesterSlashing<E> {
self.slashing
fn intermediate(&self) -> &AttesterSlashingRef<'a, E> {
&self.slashing
}
fn convert_to_object(slashing: &AttesterSlashing<E>) -> AttesterSlashing<E> {
slashing.clone()
fn convert_to_object(slashing: &AttesterSlashingRef<'a, E>) -> AttesterSlashing<E> {
slashing.clone_as_attester_slashing()
}
/// Get the set of elements covered.
@@ -58,7 +58,7 @@ impl<'a, E: EthSpec> MaxCover for AttesterSlashingMaxCover<'a, E> {
/// Update the set of items covered, for the inclusion of some object in the solution.
fn update_covering_set(
&mut self,
_best_slashing: &AttesterSlashing<E>,
_best_slashing: &AttesterSlashingRef<'a, E>,
covered_validator_indices: &HashMap<u64, u64>,
) {
self.effective_balances

View File

@@ -428,7 +428,7 @@ impl<E: EthSpec> OperationPool<E> {
let relevant_attester_slashings = reader.iter().flat_map(|slashing| {
if slashing.signature_is_still_valid(&state.fork()) {
AttesterSlashingMaxCover::new(slashing.as_inner(), to_be_slashed, state)
AttesterSlashingMaxCover::new(slashing.as_inner().to_ref(), to_be_slashed, state)
} else {
None
}
@@ -442,7 +442,7 @@ impl<E: EthSpec> OperationPool<E> {
.into_iter()
.map(|cover| {
to_be_slashed.extend(cover.covering_set().keys());
cover.intermediate().clone()
AttesterSlashingMaxCover::convert_to_object(cover.intermediate())
})
.collect()
}
@@ -463,16 +463,19 @@ impl<E: EthSpec> OperationPool<E> {
// Check that the attestation's signature is still valid wrt the fork version.
let signature_ok = slashing.signature_is_still_valid(&head_state.fork());
// Slashings that don't slash any validators can also be dropped.
let slashing_ok =
get_slashable_indices_modular(head_state, slashing.as_inner(), |_, validator| {
let slashing_ok = get_slashable_indices_modular(
head_state,
slashing.as_inner().to_ref(),
|_, validator| {
// Declare that a validator is still slashable if they have not exited prior
// to the finalized epoch.
//
// We cannot check the `slashed` field since the `head` is not finalized and
// a fork could un-slash someone.
validator.exit_epoch > head_state.finalized_checkpoint().epoch
})
.map_or(false, |indices| !indices.is_empty());
},
)
.map_or(false, |indices| !indices.is_empty());
signature_ok && slashing_ok
});
@@ -907,8 +910,8 @@ mod release_tests {
})
.unwrap();
let att1_indices = get_attesting_indices_from_state(&state, &att1).unwrap();
let att2_indices = get_attesting_indices_from_state(&state, &att2).unwrap();
let att1_indices = get_attesting_indices_from_state(&state, att1.to_ref()).unwrap();
let att2_indices = get_attesting_indices_from_state(&state, att2.to_ref()).unwrap();
let att1_split = SplitAttestation::new(att1.clone(), att1_indices);
let att2_split = SplitAttestation::new(att2.clone(), att2_indices);
@@ -981,7 +984,8 @@ mod release_tests {
for (atts, _) in attestations {
for (att, _) in atts {
let attesting_indices = get_attesting_indices_from_state(&state, &att).unwrap();
let attesting_indices =
get_attesting_indices_from_state(&state, att.to_ref()).unwrap();
op_pool.insert_attestation(att, attesting_indices).unwrap();
}
}
@@ -1051,7 +1055,7 @@ mod release_tests {
for (_, aggregate) in attestations {
let att = aggregate.unwrap().message.aggregate;
let attesting_indices = get_attesting_indices_from_state(&state, &att).unwrap();
let attesting_indices = get_attesting_indices_from_state(&state, att.to_ref()).unwrap();
op_pool
.insert_attestation(att.clone(), attesting_indices.clone())
.unwrap();
@@ -1139,7 +1143,8 @@ mod release_tests {
.collect::<Vec<_>>();
for att in aggs1.into_iter().chain(aggs2.into_iter()) {
let attesting_indices = get_attesting_indices_from_state(&state, &att).unwrap();
let attesting_indices =
get_attesting_indices_from_state(&state, att.to_ref()).unwrap();
op_pool.insert_attestation(att, attesting_indices).unwrap();
}
}
@@ -1211,7 +1216,8 @@ mod release_tests {
.collect::<Vec<_>>();
for att in aggs {
let attesting_indices = get_attesting_indices_from_state(&state, &att).unwrap();
let attesting_indices =
get_attesting_indices_from_state(&state, att.to_ref()).unwrap();
op_pool.insert_attestation(att, attesting_indices).unwrap();
}
};
@@ -1306,7 +1312,8 @@ mod release_tests {
.collect::<Vec<_>>();
for att in aggs {
let attesting_indices = get_attesting_indices_from_state(&state, &att).unwrap();
let attesting_indices =
get_attesting_indices_from_state(&state, att.to_ref()).unwrap();
op_pool.insert_attestation(att, attesting_indices).unwrap();
}
};
@@ -1349,7 +1356,7 @@ mod release_tests {
reward_cache.update(&state).unwrap();
for att in best_attestations {
let attesting_indices = get_attesting_indices_from_state(&state, &att).unwrap();
let attesting_indices = get_attesting_indices_from_state(&state, att.to_ref()).unwrap();
let split_attestation = SplitAttestation::new(att, attesting_indices);
let mut fresh_validators_rewards = AttMaxCover::new(
split_attestation.as_ref(),

View File

@@ -39,9 +39,7 @@ pub struct PersistedOperationPool<E: EthSpec> {
pub attestations: Vec<(Attestation<E>, Vec<u64>)>,
/// Mapping from sync contribution ID to sync contributions and aggregate.
pub sync_contributions: PersistedSyncContributions<E>,
/// [DEPRECATED] Attester slashings.
#[superstruct(only(V5))]
pub attester_slashings_v5: Vec<(AttesterSlashing<E>, ForkVersion)>,
/// TODO(electra): we've made a DB change here!!!
/// Attester slashings.
#[superstruct(only(V12, V14, V15))]
pub attester_slashings: Vec<SigVerifiedOp<AttesterSlashing<E>, E>>,