Optimise attester slashing processing.
This commit is contained in:
parent
e7fba3a473
commit
3f98849362
@ -13,6 +13,7 @@ pub use verify_deposit::{
|
|||||||
build_public_key_hashmap, get_existing_validator_index, verify_deposit, verify_deposit_index,
|
build_public_key_hashmap, get_existing_validator_index, verify_deposit, verify_deposit_index,
|
||||||
};
|
};
|
||||||
pub use verify_exit::verify_exit;
|
pub use verify_exit::verify_exit;
|
||||||
|
pub use verify_slashable_attestation::verify_slashable_attestation;
|
||||||
pub use verify_transfer::{execute_transfer, verify_transfer};
|
pub use verify_transfer::{execute_transfer, verify_transfer};
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
@ -264,19 +265,40 @@ pub fn process_attester_slashings(
|
|||||||
Invalid::MaxAttesterSlashingsExceed
|
Invalid::MaxAttesterSlashingsExceed
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verify attester slashings in parallel.
|
// Verify the `SlashableAttestation`s in parallel (these are the resource-consuming objects, not
|
||||||
attester_slashings
|
// the `AttesterSlashing`s themselves).
|
||||||
|
let mut slashable_attestations: Vec<&SlashableAttestation> =
|
||||||
|
Vec::with_capacity(attester_slashings.len() * 2);
|
||||||
|
for attester_slashing in attester_slashings {
|
||||||
|
slashable_attestations.push(&attester_slashing.slashable_attestation_1);
|
||||||
|
slashable_attestations.push(&attester_slashing.slashable_attestation_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify slashable attestations in parallel.
|
||||||
|
slashable_attestations
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.try_for_each(|(i, attester_slashing)| {
|
.try_for_each(|(i, slashable_attestation)| {
|
||||||
verify_attester_slashing(&state, &attester_slashing, spec)
|
verify_slashable_attestation(&state, slashable_attestation, spec)
|
||||||
.map_err(|e| e.into_with_index(i))
|
.map_err(|e| e.into_with_index(i))
|
||||||
})?;
|
})?;
|
||||||
|
let all_slashable_attestations_have_been_checked = true;
|
||||||
|
|
||||||
// Gather the slashable indices and update the state in series.
|
// Gather the slashable indices and preform the final verification and update the state in series.
|
||||||
for (i, attester_slashing) in attester_slashings.iter().enumerate() {
|
for (i, attester_slashing) in attester_slashings.iter().enumerate() {
|
||||||
|
let should_verify_slashable_attestations = !all_slashable_attestations_have_been_checked;
|
||||||
|
|
||||||
|
verify_attester_slashing(
|
||||||
|
&state,
|
||||||
|
&attester_slashing,
|
||||||
|
should_verify_slashable_attestations,
|
||||||
|
spec,
|
||||||
|
)
|
||||||
|
.map_err(|e| e.into_with_index(i))?;
|
||||||
|
|
||||||
let slashable_indices = gather_attester_slashing_indices(&state, &attester_slashing)
|
let slashable_indices = gather_attester_slashing_indices(&state, &attester_slashing)
|
||||||
.map_err(|e| e.into_with_index(i))?;
|
.map_err(|e| e.into_with_index(i))?;
|
||||||
|
|
||||||
for i in slashable_indices {
|
for i in slashable_indices {
|
||||||
state.slash_validator(i as usize, spec)?;
|
state.slash_validator(i as usize, spec)?;
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,10 @@ pub enum BlockInvalid {
|
|||||||
MaxExitsExceeded,
|
MaxExitsExceeded,
|
||||||
MaxTransfersExceed,
|
MaxTransfersExceed,
|
||||||
AttestationInvalid(usize, AttestationInvalid),
|
AttestationInvalid(usize, AttestationInvalid),
|
||||||
|
/// A `SlashableAttestation` inside an `AttesterSlashing` was invalid.
|
||||||
|
///
|
||||||
|
/// To determine the offending `AttesterSlashing` index, divide the error message `usize` by two.
|
||||||
|
SlashableAttestationInvalid(usize, SlashableAttestationInvalid),
|
||||||
AttesterSlashingInvalid(usize, AttesterSlashingInvalid),
|
AttesterSlashingInvalid(usize, AttesterSlashingInvalid),
|
||||||
ProposerSlashingInvalid(usize, ProposerSlashingInvalid),
|
ProposerSlashingInvalid(usize, ProposerSlashingInvalid),
|
||||||
DepositInvalid(usize, DepositInvalid),
|
DepositInvalid(usize, DepositInvalid),
|
||||||
@ -235,6 +239,11 @@ impl Into<SlashableAttestationInvalid> for SlashableAttestationValidationError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_into_with_index_without_beacon_error!(
|
||||||
|
SlashableAttestationValidationError,
|
||||||
|
SlashableAttestationInvalid
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* `ProposerSlashing` Validation
|
* `ProposerSlashing` Validation
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,7 @@ use types::*;
|
|||||||
pub fn verify_attester_slashing(
|
pub fn verify_attester_slashing(
|
||||||
state: &BeaconState,
|
state: &BeaconState,
|
||||||
attester_slashing: &AttesterSlashing,
|
attester_slashing: &AttesterSlashing,
|
||||||
|
should_verify_slashable_attestations: bool,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let slashable_attestation_1 = &attester_slashing.slashable_attestation_1;
|
let slashable_attestation_1 = &attester_slashing.slashable_attestation_1;
|
||||||
@ -26,10 +27,12 @@ pub fn verify_attester_slashing(
|
|||||||
Invalid::NotSlashable
|
Invalid::NotSlashable
|
||||||
);
|
);
|
||||||
|
|
||||||
verify_slashable_attestation(state, &slashable_attestation_1, spec)
|
if should_verify_slashable_attestations {
|
||||||
.map_err(|e| Error::Invalid(Invalid::SlashableAttestation1Invalid(e.into())))?;
|
verify_slashable_attestation(state, &slashable_attestation_1, spec)
|
||||||
verify_slashable_attestation(state, &slashable_attestation_2, spec)
|
.map_err(|e| Error::Invalid(Invalid::SlashableAttestation1Invalid(e.into())))?;
|
||||||
.map_err(|e| Error::Invalid(Invalid::SlashableAttestation2Invalid(e.into())))?;
|
verify_slashable_attestation(state, &slashable_attestation_2, spec)
|
||||||
|
.map_err(|e| Error::Invalid(Invalid::SlashableAttestation2Invalid(e.into())))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user