Attestation superstruct changes for EIP 7549 (#5644)

* update

* experiment

* superstruct changes

* revert

* superstruct changes

* fix tests

* indexed attestation

* indexed attestation superstruct

* updated TODOs
This commit is contained in:
Eitan Seri-Levi
2024-04-30 19:49:08 +03:00
committed by GitHub
parent 4a48d7b546
commit 3b7132bc0d
56 changed files with 943 additions and 429 deletions

View File

@@ -226,12 +226,12 @@ impl TargetArrayChunk for MinTargetChunk {
) -> Result<AttesterSlashingStatus<E>, Error> {
let min_target =
self.chunk
.get_target(validator_index, attestation.data.source.epoch, config)?;
if attestation.data.target.epoch > min_target {
.get_target(validator_index, attestation.data().source.epoch, config)?;
if attestation.data().target.epoch > min_target {
let existing_attestation =
db.get_attestation_for_validator(txn, validator_index, min_target)?;
if attestation.data.source.epoch < existing_attestation.data.source.epoch {
if attestation.data().source.epoch < existing_attestation.data().source.epoch {
Ok(AttesterSlashingStatus::SurroundsExisting(Box::new(
existing_attestation,
)))
@@ -329,12 +329,12 @@ impl TargetArrayChunk for MaxTargetChunk {
) -> Result<AttesterSlashingStatus<E>, Error> {
let max_target =
self.chunk
.get_target(validator_index, attestation.data.source.epoch, config)?;
if attestation.data.target.epoch < max_target {
.get_target(validator_index, attestation.data().source.epoch, config)?;
if attestation.data().target.epoch < max_target {
let existing_attestation =
db.get_attestation_for_validator(txn, validator_index, max_target)?;
if existing_attestation.data.source.epoch < attestation.data.source.epoch {
if existing_attestation.data().source.epoch < attestation.data().source.epoch {
Ok(AttesterSlashingStatus::SurroundedByExisting(Box::new(
existing_attestation,
)))
@@ -428,7 +428,7 @@ pub fn apply_attestation_for_validator<E: EthSpec, T: TargetArrayChunk>(
current_epoch: Epoch,
config: &Config,
) -> Result<AttesterSlashingStatus<E>, Error> {
let mut chunk_index = config.chunk_index(attestation.data.source.epoch);
let mut chunk_index = config.chunk_index(attestation.data().source.epoch);
let mut current_chunk = get_chunk_for_update(
db,
txn,
@@ -446,7 +446,7 @@ pub fn apply_attestation_for_validator<E: EthSpec, T: TargetArrayChunk>(
}
let Some(mut start_epoch) =
T::first_start_epoch(attestation.data.source.epoch, current_epoch, config)
T::first_start_epoch(attestation.data().source.epoch, current_epoch, config)
else {
return Ok(slashing_status);
};
@@ -465,7 +465,7 @@ pub fn apply_attestation_for_validator<E: EthSpec, T: TargetArrayChunk>(
chunk_index,
validator_index,
start_epoch,
attestation.data.target.epoch,
attestation.data().target.epoch,
current_epoch,
config,
)?;
@@ -492,7 +492,7 @@ pub fn update<E: EthSpec>(
let mut chunk_attestations = BTreeMap::new();
for attestation in batch {
chunk_attestations
.entry(config.chunk_index(attestation.indexed.data.source.epoch))
.entry(config.chunk_index(attestation.indexed.data().source.epoch))
.or_insert_with(Vec::new)
.push(attestation);
}

View File

@@ -47,7 +47,8 @@ impl<E: EthSpec> AttestationBatch<E> {
self.attestations.push(Arc::downgrade(&indexed_record));
let attestation_data_hash = indexed_record.record.attestation_data_hash;
for &validator_index in &indexed_record.indexed.attesting_indices {
for &validator_index in indexed_record.indexed.attesting_indices_iter() {
self.attesters
.entry((validator_index, attestation_data_hash))
.and_modify(|existing_entry| {
@@ -56,8 +57,8 @@ impl<E: EthSpec> AttestationBatch<E> {
// smaller indexed attestation. Single-bit attestations will usually be removed
// completely by this process, and aggregates will only be retained if they
// are not redundant with respect to a larger aggregate seen in the same batch.
if existing_entry.indexed.attesting_indices.len()
< indexed_record.indexed.attesting_indices.len()
if existing_entry.indexed.attesting_indices_len()
< indexed_record.indexed.attesting_indices_len()
{
*existing_entry = indexed_record.clone();
}

View File

@@ -80,18 +80,20 @@ impl<E: EthSpec> IndexedAttesterRecord<E> {
#[derive(Debug, Clone, Encode, Decode, TreeHash)]
struct IndexedAttestationHeader<E: EthSpec> {
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerCommittee>,
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerCommitteePerSlot>,
pub data_root: Hash256,
pub signature: AggregateSignature,
}
impl<E: EthSpec> From<IndexedAttestation<E>> for AttesterRecord {
fn from(indexed_attestation: IndexedAttestation<E>) -> AttesterRecord {
let attestation_data_hash = indexed_attestation.data.tree_hash_root();
let attestation_data_hash = indexed_attestation.data().tree_hash_root();
let attesting_indices =
VariableList::new(indexed_attestation.attesting_indices_to_vec()).unwrap_or_default();
let header = IndexedAttestationHeader::<E> {
attesting_indices: indexed_attestation.attesting_indices,
attesting_indices,
data_root: attestation_data_hash,
signature: indexed_attestation.signature,
signature: indexed_attestation.signature().clone(),
};
let indexed_attestation_hash = header.tree_hash_root();
AttesterRecord {

View File

@@ -166,8 +166,7 @@ impl Config {
validator_chunk_index: usize,
) -> impl Iterator<Item = u64> + 'a {
attestation
.attesting_indices
.iter()
.attesting_indices_iter()
.filter(move |v| self.validator_chunk_index(**v) == validator_chunk_index)
.copied()
}

View File

@@ -438,7 +438,7 @@ impl<E: EthSpec> SlasherDB<E> {
) -> Result<u64, Error> {
// Look-up ID by hash.
let id_key = IndexedAttestationIdKey::new(
indexed_attestation.data.target.epoch,
indexed_attestation.data().target.epoch,
indexed_attestation_hash,
);
@@ -500,7 +500,7 @@ impl<E: EthSpec> SlasherDB<E> {
// Otherwise, load the indexed attestation, compute the root and cache it.
let indexed_attestation = self.get_indexed_attestation(txn, indexed_id)?;
let attestation_data_root = indexed_attestation.data.tree_hash_root();
let attestation_data_root = indexed_attestation.data().tree_hash_root();
cache.put(indexed_id, attestation_data_root);
@@ -536,7 +536,7 @@ impl<E: EthSpec> SlasherDB<E> {
indexed_attestation_id: IndexedAttestationId,
) -> Result<AttesterSlashingStatus<E>, Error> {
// See if there's an existing attestation for this attester.
let target_epoch = attestation.data.target.epoch;
let target_epoch = attestation.data().target.epoch;
let prev_max_target = self.get_attester_max_target(validator_index, txn)?;

View File

@@ -299,7 +299,7 @@ impl<E: EthSpec> Slasher<E> {
self.log,
"Found double-vote slashing";
"validator_index" => validator_index,
"epoch" => slashing.attestation_1.data.target.epoch,
"epoch" => slashing.attestation_1.data().target.epoch,
);
slashings.insert(slashing);
}
@@ -325,8 +325,8 @@ impl<E: EthSpec> Slasher<E> {
for indexed_record in batch {
let attestation = &indexed_record.indexed;
let target_epoch = attestation.data.target.epoch;
let source_epoch = attestation.data.source.epoch;
let target_epoch = attestation.data().target.epoch;
let source_epoch = attestation.data().source.epoch;
if source_epoch > target_epoch
|| source_epoch + self.config.history_length as u64 <= current_epoch

View File

@@ -1,7 +1,8 @@
use std::collections::HashSet;
use types::{
AggregateSignature, AttestationData, AttesterSlashing, BeaconBlockHeader, Checkpoint, Epoch,
Hash256, IndexedAttestation, MainnetEthSpec, Signature, SignedBeaconBlockHeader, Slot,
indexed_attestation::IndexedAttestationBase, AggregateSignature, AttestationData,
AttesterSlashing, BeaconBlockHeader, Checkpoint, Epoch, Hash256, IndexedAttestation,
MainnetEthSpec, Signature, SignedBeaconBlockHeader, Slot,
};
pub type E = MainnetEthSpec;
@@ -12,7 +13,8 @@ pub fn indexed_att(
target_epoch: u64,
target_root: u64,
) -> IndexedAttestation<E> {
IndexedAttestation {
// TODO(electra) make fork-agnostic
IndexedAttestation::Base(IndexedAttestationBase {
attesting_indices: attesting_indices.as_ref().to_vec().into(),
data: AttestationData {
slot: Slot::new(0),
@@ -28,7 +30,7 @@ pub fn indexed_att(
},
},
signature: AggregateSignature::empty(),
}
})
}
pub fn att_slashing(
@@ -66,7 +68,9 @@ pub fn slashed_validators_from_slashings(slashings: &HashSet<AttesterSlashing<E>
"invalid slashing: {:#?}",
slashing
);
hashset_intersection(&att1.attesting_indices, &att2.attesting_indices)
let attesting_indices_1 = att1.attesting_indices_to_vec();
let attesting_indices_2 = att2.attesting_indices_to_vec();
hashset_intersection(&attesting_indices_1, &attesting_indices_2)
})
.collect()
}
@@ -82,10 +86,14 @@ pub fn slashed_validators_from_attestations(
continue;
}
// TODO(electra) in a nested loop, copying to vecs feels bad
let attesting_indices_1 = att1.attesting_indices_to_vec();
let attesting_indices_2 = att2.attesting_indices_to_vec();
if att1.is_double_vote(att2) || att1.is_surround_vote(att2) {
slashed_validators.extend(hashset_intersection(
&att1.attesting_indices,
&att2.attesting_indices,
&attesting_indices_1,
&attesting_indices_2,
));
}
}