mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Check slashability of attestations in batches to avoid sequential bottleneck (#8516)
Closes: - https://github.com/sigp/lighthouse/issues/1914 Sign attestations prior to checking them against the slashing protection DB. This allows us to avoid the sequential DB checks which are observed in traces here: - https://github.com/sigp/lighthouse/pull/8508#discussion_r2576686107 Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com> Co-Authored-By: Michael Sproul <michael@sigmaprime.io> Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>
This commit is contained in:
@@ -539,6 +539,58 @@ mod tests {
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Assert that a slashable attestation fails to be signed locally (empty result) and is
|
||||
/// either signed or not by the web3signer rig depending on the value of
|
||||
/// `web3signer_should_sign`.
|
||||
///
|
||||
/// The batch attestation signing API returns an empty result instead of an error for
|
||||
/// slashable attestations.
|
||||
pub async fn assert_slashable_attestation_should_sign<F, R>(
|
||||
self,
|
||||
case_name: &str,
|
||||
generate_sig: F,
|
||||
web3signer_should_sign: bool,
|
||||
) -> Self
|
||||
where
|
||||
F: Fn(PublicKeyBytes, Arc<LighthouseValidatorStore<TestingSlotClock, E>>) -> R,
|
||||
R: Future<
|
||||
Output = Result<Vec<(u64, Attestation<E>)>, lighthouse_validator_store::Error>,
|
||||
>,
|
||||
{
|
||||
for validator_rig in &self.validator_rigs {
|
||||
let result =
|
||||
generate_sig(self.validator_pubkey, validator_rig.validator_store.clone())
|
||||
.await;
|
||||
|
||||
if !validator_rig.using_web3signer || !web3signer_should_sign {
|
||||
// For local validators, slashable attestations should return an empty result
|
||||
// or an error.
|
||||
match result {
|
||||
Ok(attestations) => {
|
||||
assert!(
|
||||
attestations.is_empty(),
|
||||
"should not sign slashable {case_name}: expected empty result"
|
||||
);
|
||||
}
|
||||
Err(ValidatorStoreError::Slashable(_)) => {
|
||||
// Also acceptable - error indicates slashable
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("unexpected error for slashable {case_name}: {e:?}");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Web3signer should sign (has its own slashing protection)
|
||||
let attestations = result.expect("should sign slashable {case_name}");
|
||||
assert!(
|
||||
!attestations.is_empty(),
|
||||
"web3signer should sign slashable {case_name}"
|
||||
);
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a generic, arbitrary attestation for signing.
|
||||
@@ -605,12 +657,14 @@ mod tests {
|
||||
})
|
||||
.await
|
||||
.assert_signatures_match("attestation", |pubkey, validator_store| async move {
|
||||
let mut attestation = get_attestation();
|
||||
let attestation = get_attestation();
|
||||
validator_store
|
||||
.sign_attestation(pubkey, 0, &mut attestation, Epoch::new(0))
|
||||
.sign_attestations(vec![(0, pubkey, 0, attestation)])
|
||||
.await
|
||||
.unwrap();
|
||||
attestation
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap()
|
||||
.1
|
||||
})
|
||||
.await
|
||||
.assert_signatures_match("signed_aggregate", |pubkey, validator_store| async move {
|
||||
@@ -820,8 +874,6 @@ mod tests {
|
||||
block
|
||||
};
|
||||
|
||||
let current_epoch = Epoch::new(5);
|
||||
|
||||
TestingRig::new(
|
||||
network,
|
||||
slashing_protection_config,
|
||||
@@ -830,42 +882,44 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.assert_signatures_match("first_attestation", |pubkey, validator_store| async move {
|
||||
let mut attestation = first_attestation();
|
||||
let attestation = first_attestation();
|
||||
validator_store
|
||||
.sign_attestation(pubkey, 0, &mut attestation, current_epoch)
|
||||
.sign_attestations(vec![(0, pubkey, 0, attestation)])
|
||||
.await
|
||||
.unwrap();
|
||||
attestation
|
||||
.unwrap()
|
||||
.pop()
|
||||
.unwrap()
|
||||
.1
|
||||
})
|
||||
.await
|
||||
.assert_slashable_message_should_sign(
|
||||
.assert_slashable_attestation_should_sign(
|
||||
"double_vote_attestation",
|
||||
move |pubkey, validator_store| async move {
|
||||
let mut attestation = double_vote_attestation();
|
||||
let attestation = double_vote_attestation();
|
||||
validator_store
|
||||
.sign_attestation(pubkey, 0, &mut attestation, current_epoch)
|
||||
.sign_attestations(vec![(0, pubkey, 0, attestation)])
|
||||
.await
|
||||
},
|
||||
slashable_message_should_sign,
|
||||
)
|
||||
.await
|
||||
.assert_slashable_message_should_sign(
|
||||
.assert_slashable_attestation_should_sign(
|
||||
"surrounding_attestation",
|
||||
move |pubkey, validator_store| async move {
|
||||
let mut attestation = surrounding_attestation();
|
||||
let attestation = surrounding_attestation();
|
||||
validator_store
|
||||
.sign_attestation(pubkey, 0, &mut attestation, current_epoch)
|
||||
.sign_attestations(vec![(0, pubkey, 0, attestation)])
|
||||
.await
|
||||
},
|
||||
slashable_message_should_sign,
|
||||
)
|
||||
.await
|
||||
.assert_slashable_message_should_sign(
|
||||
.assert_slashable_attestation_should_sign(
|
||||
"surrounded_attestation",
|
||||
move |pubkey, validator_store| async move {
|
||||
let mut attestation = surrounded_attestation();
|
||||
let attestation = surrounded_attestation();
|
||||
validator_store
|
||||
.sign_attestation(pubkey, 0, &mut attestation, current_epoch)
|
||||
.sign_attestations(vec![(0, pubkey, 0, attestation)])
|
||||
.await
|
||||
},
|
||||
slashable_message_should_sign,
|
||||
|
||||
Reference in New Issue
Block a user