Skip to content

Commit 96db2ea

Browse files
committed
superstruct Attester Fork Variants
1 parent 05fbbdd commit 96db2ea

File tree

14 files changed

+204
-60
lines changed

14 files changed

+204
-60
lines changed

consensus/fork_choice/src/fork_choice.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,8 @@ where
10931093
.copied()
10941094
.collect::<BTreeSet<_>>()
10951095
};
1096-
let att1_indices = attesting_indices_set(&slashing.attestation_1);
1097-
let att2_indices = attesting_indices_set(&slashing.attestation_2);
1096+
let att1_indices = attesting_indices_set(slashing.attestation_1());
1097+
let att2_indices = attesting_indices_set(slashing.attestation_2());
10981098
self.fc_store
10991099
.extend_equivocating_indices(att1_indices.intersection(&att2_indices).copied());
11001100
}

consensus/state_processing/src/per_block_processing/block_signature_verifier.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,12 @@ where
247247
) -> Result<()> {
248248
self.sets
249249
.sets
250-
.reserve(block.message().body().attester_slashings().len() * 2);
250+
.reserve(block.message().body().attester_slashings_len() * 2);
251251

252252
block
253253
.message()
254254
.body()
255255
.attester_slashings()
256-
.iter()
257256
.try_for_each(|attester_slashing| {
258257
let (set_1, set_2) = attester_slashing_signature_sets(
259258
self.state,

consensus/state_processing/src/per_block_processing/process_operations.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,19 @@ pub fn process_proposer_slashings<E: EthSpec>(
230230
///
231231
/// Returns `Ok(())` if the validation and state updates completed successfully, otherwise returns
232232
/// an `Err` describing the invalid object or cause of failure.
233-
pub fn process_attester_slashings<E: EthSpec>(
233+
pub fn process_attester_slashings<'a, E: EthSpec, I>(
234234
state: &mut BeaconState<E>,
235-
attester_slashings: &[AttesterSlashing<E>],
235+
attester_slashings: I,
236236
verify_signatures: VerifySignatures,
237237
ctxt: &mut ConsensusContext<E>,
238238
spec: &ChainSpec,
239-
) -> Result<(), BlockProcessingError> {
239+
) -> Result<(), BlockProcessingError>
240+
where
241+
I: Iterator<Item = AttesterSlashingRef<'a, E>>,
242+
{
240243
state.build_slashings_cache()?;
241244

242-
for (i, attester_slashing) in attester_slashings.iter().enumerate() {
245+
for (i, attester_slashing) in attester_slashings.enumerate() {
243246
let slashable_indices =
244247
verify_attester_slashing(state, attester_slashing, verify_signatures, spec)
245248
.map_err(|e| e.into_with_index(i))?;

consensus/state_processing/src/per_block_processing/signature_sets.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use ssz::DecodeError;
77
use std::borrow::Cow;
88
use tree_hash::TreeHash;
99
use types::{
10-
AbstractExecPayload, AggregateSignature, AttesterSlashing, BeaconBlockRef, BeaconState,
10+
AbstractExecPayload, AggregateSignature, AttesterSlashingRef, BeaconBlockRef, BeaconState,
1111
BeaconStateError, ChainSpec, DepositData, Domain, Epoch, EthSpec, Fork, Hash256,
1212
InconsistentFork, IndexedAttestation, ProposerSlashing, PublicKey, PublicKeyBytes, Signature,
1313
SignedAggregateAndProof, SignedBeaconBlock, SignedBeaconBlockHeader,
@@ -335,7 +335,7 @@ where
335335
pub fn attester_slashing_signature_sets<'a, E, F>(
336336
state: &'a BeaconState<E>,
337337
get_pubkey: F,
338-
attester_slashing: &'a AttesterSlashing<E>,
338+
attester_slashing: AttesterSlashingRef<'a, E>,
339339
spec: &'a ChainSpec,
340340
) -> Result<(SignatureSet<'a>, SignatureSet<'a>)>
341341
where
@@ -346,15 +346,15 @@ where
346346
indexed_attestation_signature_set(
347347
state,
348348
get_pubkey.clone(),
349-
&attester_slashing.attestation_1.signature,
350-
&attester_slashing.attestation_1,
349+
&attester_slashing.attestation_1().signature,
350+
&attester_slashing.attestation_1(),
351351
spec,
352352
)?,
353353
indexed_attestation_signature_set(
354354
state,
355355
get_pubkey,
356-
&attester_slashing.attestation_2.signature,
357-
&attester_slashing.attestation_2,
356+
&attester_slashing.attestation_2().signature,
357+
&attester_slashing.attestation_2(),
358358
spec,
359359
)?,
360360
))

consensus/state_processing/src/per_block_processing/verify_attester_slashing.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ fn error(reason: Invalid) -> BlockOperationError<Invalid> {
1616
/// Returns `Ok(indices)` with `indices` being a non-empty vec of validator indices in ascending
1717
/// order if the `AttesterSlashing` is valid. Otherwise returns `Err(e)` with the reason for
1818
/// invalidity.
19-
pub fn verify_attester_slashing<E: EthSpec>(
19+
pub fn verify_attester_slashing<'a, E: EthSpec>(
2020
state: &BeaconState<E>,
21-
attester_slashing: &AttesterSlashing<E>,
21+
attester_slashing: AttesterSlashingRef<'a, E>,
2222
verify_signatures: VerifySignatures,
2323
spec: &ChainSpec,
2424
) -> Result<Vec<u64>> {
25-
let attestation_1 = &attester_slashing.attestation_1;
26-
let attestation_2 = &attester_slashing.attestation_2;
25+
let attestation_1 = attester_slashing.attestation_1();
26+
let attestation_2 = attester_slashing.attestation_2();
2727

2828
// Spec: is_slashable_attestation_data
2929
verify!(
@@ -43,9 +43,9 @@ pub fn verify_attester_slashing<E: EthSpec>(
4343
/// For a given attester slashing, return the indices able to be slashed in ascending order.
4444
///
4545
/// Returns Ok(indices) if `indices.len() > 0`
46-
pub fn get_slashable_indices<E: EthSpec>(
46+
pub fn get_slashable_indices<'a, E: EthSpec>(
4747
state: &BeaconState<E>,
48-
attester_slashing: &AttesterSlashing<E>,
48+
attester_slashing: AttesterSlashingRef<'a, E>,
4949
) -> Result<Vec<u64>> {
5050
get_slashable_indices_modular(state, attester_slashing, |_, validator| {
5151
validator.is_slashable_at(state.current_epoch())
@@ -54,16 +54,16 @@ pub fn get_slashable_indices<E: EthSpec>(
5454

5555
/// Same as `gather_attester_slashing_indices` but allows the caller to specify the criteria
5656
/// for determining whether a given validator should be considered slashable.
57-
pub fn get_slashable_indices_modular<F, E: EthSpec>(
57+
pub fn get_slashable_indices_modular<'a, F, E: EthSpec>(
5858
state: &BeaconState<E>,
59-
attester_slashing: &AttesterSlashing<E>,
59+
attester_slashing: AttesterSlashingRef<'a, E>,
6060
is_slashable: F,
6161
) -> Result<Vec<u64>>
6262
where
6363
F: Fn(u64, &Validator) -> bool,
6464
{
65-
let attestation_1 = &attester_slashing.attestation_1;
66-
let attestation_2 = &attester_slashing.attestation_2;
65+
let attestation_1 = attester_slashing.attestation_1();
66+
let attestation_2 = attester_slashing.attestation_2();
6767

6868
let attesting_indices_1 = attestation_1
6969
.attesting_indices

consensus/state_processing/src/verify_operation.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use smallvec::{smallvec, SmallVec};
1212
use ssz::{Decode, Encode};
1313
use ssz_derive::{Decode, Encode};
1414
use std::marker::PhantomData;
15+
use types::{AttesterSlashingBase, AttesterSlashingElectra, AttesterSlashingRef};
1516
use types::{
16-
AttesterSlashing, BeaconState, ChainSpec, Epoch, EthSpec, Fork, ForkVersion, ProposerSlashing,
17+
BeaconState, ChainSpec, Epoch, EthSpec, Fork, ForkVersion, ProposerSlashing,
1718
SignedBlsToExecutionChange, SignedVoluntaryExit,
1819
};
1920

@@ -144,15 +145,46 @@ impl<E: EthSpec> VerifyOperation<E> for SignedVoluntaryExit {
144145
}
145146
}
146147

147-
impl<E: EthSpec> VerifyOperation<E> for AttesterSlashing<E> {
148+
impl<E: EthSpec> VerifyOperation<E> for AttesterSlashingBase<E> {
148149
type Error = AttesterSlashingValidationError;
149150

150151
fn validate(
151152
self,
152153
state: &BeaconState<E>,
153154
spec: &ChainSpec,
154155
) -> Result<SigVerifiedOp<Self, E>, Self::Error> {
155-
verify_attester_slashing(state, &self, VerifySignatures::True, spec)?;
156+
verify_attester_slashing(
157+
state,
158+
AttesterSlashingRef::Base(&self),
159+
VerifySignatures::True,
160+
spec,
161+
)?;
162+
Ok(SigVerifiedOp::new(self, state))
163+
}
164+
165+
#[allow(clippy::arithmetic_side_effects)]
166+
fn verification_epochs(&self) -> SmallVec<[Epoch; MAX_FORKS_VERIFIED_AGAINST]> {
167+
smallvec![
168+
self.attestation_1.data.target.epoch,
169+
self.attestation_2.data.target.epoch
170+
]
171+
}
172+
}
173+
174+
impl<E: EthSpec> VerifyOperation<E> for AttesterSlashingElectra<E> {
175+
type Error = AttesterSlashingValidationError;
176+
177+
fn validate(
178+
self,
179+
state: &BeaconState<E>,
180+
spec: &ChainSpec,
181+
) -> Result<SigVerifiedOp<Self, E>, Self::Error> {
182+
verify_attester_slashing(
183+
state,
184+
AttesterSlashingRef::Electra(&self),
185+
VerifySignatures::True,
186+
spec,
187+
)?;
156188
Ok(SigVerifiedOp::new(self, state))
157189
}
158190

consensus/types/src/attester_slashing.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,39 @@
11
use crate::{test_utils::TestRandom, EthSpec, IndexedAttestation};
2-
32
use derivative::Derivative;
43
use serde::{Deserialize, Serialize};
54
use ssz_derive::{Decode, Encode};
5+
use superstruct::superstruct;
66
use test_random_derive::TestRandom;
77
use tree_hash_derive::TreeHash;
88

9-
/// Two conflicting attestations.
10-
///
11-
/// Spec v0.12.1
9+
#[superstruct(
10+
variants(Base, Electra),
11+
variant_attributes(
12+
derive(
13+
Derivative,
14+
Debug,
15+
Clone,
16+
Serialize,
17+
Deserialize,
18+
Encode,
19+
Decode,
20+
TreeHash,
21+
TestRandom,
22+
arbitrary::Arbitrary
23+
),
24+
derivative(PartialEq, Eq, Hash(bound = "E: EthSpec")),
25+
serde(bound = "E: EthSpec"),
26+
arbitrary(bound = "E: EthSpec")
27+
)
28+
)]
1229
#[derive(
13-
Derivative,
14-
Debug,
15-
Clone,
16-
Serialize,
17-
Deserialize,
18-
Encode,
19-
Decode,
20-
TreeHash,
21-
TestRandom,
22-
arbitrary::Arbitrary,
30+
Debug, Clone, Serialize, Encode, Deserialize, TreeHash, Derivative, arbitrary::Arbitrary,
2331
)]
2432
#[derivative(PartialEq, Eq, Hash(bound = "E: EthSpec"))]
25-
#[serde(bound = "E: EthSpec")]
33+
#[serde(bound = "E: EthSpec", untagged)]
2634
#[arbitrary(bound = "E: EthSpec")]
35+
#[ssz(enum_behaviour = "transparent")]
36+
#[tree_hash(enum_behaviour = "transparent")]
2737
pub struct AttesterSlashing<E: EthSpec> {
2838
pub attestation_1: IndexedAttestation<E>,
2939
pub attestation_2: IndexedAttestation<E>,

consensus/types/src/beacon_block.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBase<E, Payload> {
345345
signed_header_2: signed_header,
346346
};
347347

348-
let attester_slashing = AttesterSlashing {
348+
let attester_slashing = AttesterSlashingBase {
349349
attestation_1: indexed_attestation.clone(),
350350
attestation_2: indexed_attestation,
351351
};
@@ -603,6 +603,25 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockElectra<E, Payload>
603603
/// Return a Electra block where the block has maximum size.
604604
pub fn full(spec: &ChainSpec) -> Self {
605605
let base_block: BeaconBlockBase<_, Payload> = BeaconBlockBase::full(spec);
606+
let indexed_attestation: IndexedAttestation<E> = IndexedAttestation {
607+
attesting_indices: VariableList::new(vec![
608+
0_u64;
609+
E::MaxValidatorsPerCommittee::to_usize()
610+
])
611+
.unwrap(),
612+
data: AttestationData::default(),
613+
signature: AggregateSignature::empty(),
614+
};
615+
// TODO(electra): fix this so we calculate this size correctly
616+
let attester_slashings = vec![
617+
AttesterSlashingElectra {
618+
attestation_1: indexed_attestation.clone(),
619+
attestation_2: indexed_attestation,
620+
};
621+
E::max_attester_slashings_electra()
622+
]
623+
.into();
624+
606625
let bls_to_execution_changes = vec![
607626
SignedBlsToExecutionChange {
608627
message: BlsToExecutionChange {
@@ -626,7 +645,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockElectra<E, Payload>
626645
state_root: Hash256::zero(),
627646
body: BeaconBlockBodyElectra {
628647
proposer_slashings: base_block.body.proposer_slashings,
629-
attester_slashings: base_block.body.attester_slashings,
648+
attester_slashings,
630649
attestations: base_block.body.attestations,
631650
deposits: base_block.body.deposits,
632651
voluntary_exits: base_block.body.voluntary_exits,
@@ -641,6 +660,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockElectra<E, Payload>
641660
graffiti: Graffiti::default(),
642661
execution_payload: Payload::Electra::default(),
643662
blob_kzg_commitments: VariableList::empty(),
663+
consolidations: VariableList::empty(),
644664
},
645665
}
646666
}
@@ -671,6 +691,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> EmptyBlock for BeaconBlockElec
671691
execution_payload: Payload::Electra::default(),
672692
bls_to_execution_changes: VariableList::empty(),
673693
blob_kzg_commitments: VariableList::empty(),
694+
consolidations: VariableList::empty(),
674695
},
675696
}
676697
}

0 commit comments

Comments
 (0)