-
Notifications
You must be signed in to change notification settings - Fork 42
perf: improve attestations efficiency #1392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note: The validation included in pub fn validate(&self) -> Result<(), BLST_ERROR> {
unsafe {
if $pk_is_inf(&self.point) {
return Err(BLST_ERROR::BLST_PK_IS_INFINITY);
}
if !$pk_in_group(&self.point) {
return Err(BLST_ERROR::BLST_POINT_NOT_IN_GROUP);
}
}
Ok(())
}(As well as the Infinity Publick Check that we are still doing) |
rodrigo-o
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM given the explanation! I added just a small comment related to the unwrap.
native/bls_nif/src/lib.rs
Outdated
| PublicKey::deserialize_uncompressed(pk.serialize().as_slice()) | ||
| // This unwrap() is safe as the Public Key is created from an uncompressed valid key | ||
| .unwrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Bubbling the error should be better than the unwrap even if its something that shouldn't be reached, in any case we'll have an issue, we could go with something like:
fn fast_public_key_deserialize(pk: &[u8]) -> Result<PublicKey, String> {
if pk == &bls::INFINITY_PUBLIC_KEY[..] {
Err("Infinity public Key".to_owned())
} else {
bls::impls::blst::types::PublicKey::from_bytes(pk)
.map_err(|err| format!("BlstError({:?})", err))
.and_then(|pk| {
PublicKey::deserialize_uncompressed(pk.serialize().as_slice())
.map_err(|e| format!("Deserialization error: {:?}", e))
})
}
}
Motivation
Attestation check is taking more than 2 seconds in two different moments of the slot processing.
After profiling it was discovered that most of the time was consumed in deserializing the attesters public keys.
On mainnet we have almost all slots with 128 attestations, and around 500 attesters on each. Taking about 20ms each attestation validation and more than 2 seconds for all the 128 attestations.
Note the limit of attester per attestation is 2048 so it can get worse. For example on Holesky we were taking about twice that time.
This matches our benchmark:
Description
This fix is actually a hack. Instead of using the provided
PublicKey::deserialization()by theblslibrary wich runs several key validations, we use a lighter deserialization that does not validate the key.These validations seemed unnecessary as the attestation fails anyway if any of the public key is invalid or has a bad encoding.
In any case, the aggregated signature validation is spec-tested and it is passing all the tests.
New benchs:
And on our application:
After

Before
