Altair consensus changes and refactors (#2279)

## Proposed Changes

Implement the consensus changes necessary for the upcoming Altair hard fork.

## Additional Info

This is quite a heavy refactor, with pivotal types like the `BeaconState` and `BeaconBlock` changing from structs to enums. This ripples through the whole codebase with field accesses changing to methods, e.g. `state.slot` => `state.slot()`.


Co-authored-by: realbigsean <seananderson33@gmail.com>
This commit is contained in:
Michael Sproul
2021-07-09 06:15:32 +00:00
parent 89361573d4
commit b4689e20c6
271 changed files with 9652 additions and 8444 deletions

View File

@@ -1,6 +1,37 @@
/// Implemented on some struct from a BLS library so it may be used internally in this crate.
pub trait TAggregatePublicKey: Sized + Clone {}
use crate::{generic_public_key::GenericPublicKey, Error};
use std::marker::PhantomData;
/*
* Note: there is no immediate need for a `GenericAggregatePublicKey` struct.
*/
/// Implemented on some struct from a BLS library so it may be used internally in this crate.
pub trait TAggregatePublicKey<Pub>: Sized + Clone {
fn to_public_key(&self) -> GenericPublicKey<Pub>;
// NOTE: this API *could* take a `&[&Pub]` as that's what the underlying library needs,
// but it seems that this type would rarely occur due to our use of wrapper structs
fn aggregate(pubkeys: &[GenericPublicKey<Pub>]) -> Result<Self, Error>;
}
/// A BLS aggregate public key that is generic across some BLS point (`AggPub`).
///
/// Provides generic functionality whilst deferring all serious cryptographic operations to `AggPub`.
#[derive(Clone)]
pub struct GenericAggregatePublicKey<Pub, AggPub> {
/// The underlying point which performs *actual* cryptographic operations.
point: AggPub,
_phantom: PhantomData<Pub>,
}
impl<Pub, AggPub> GenericAggregatePublicKey<Pub, AggPub>
where
AggPub: TAggregatePublicKey<Pub>,
{
pub fn to_public_key(&self) -> GenericPublicKey<Pub> {
self.point.to_public_key()
}
pub fn aggregate(pubkeys: &[GenericPublicKey<Pub>]) -> Result<Self, Error> {
Ok(Self {
point: AggPub::aggregate(pubkeys)?,
_phantom: PhantomData,
})
}
}

View File

@@ -173,7 +173,7 @@ where
impl<Pub, AggPub, Sig, AggSig> GenericAggregateSignature<Pub, AggPub, Sig, AggSig>
where
Pub: TPublicKey + Clone,
AggPub: TAggregatePublicKey + Clone,
AggPub: TAggregatePublicKey<Pub> + Clone,
Sig: TSignature<Pub>,
AggSig: TAggregateSignature<Pub, AggPub, Sig>,
{
@@ -189,6 +189,18 @@ where
}
}
/// Wrapper to `fast_aggregate_verify` accepting the infinity signature when `pubkeys` is empty.
pub fn eth2_fast_aggregate_verify(
&self,
msg: Hash256,
pubkeys: &[&GenericPublicKey<Pub>],
) -> bool {
if pubkeys.is_empty() && self.is_infinity {
return true;
}
self.fast_aggregate_verify(msg, pubkeys)
}
/// Verify that `self` represents an aggregate signature where all `pubkeys` have signed their
/// corresponding message in `msgs`.
///

View File

@@ -27,7 +27,7 @@ pub trait TPublicKey: Sized + Clone {
fn deserialize(bytes: &[u8]) -> Result<Self, Error>;
}
/// A BLS aggregate public key that is generic across some BLS point (`Pub`).
/// A BLS public key that is generic across some BLS point (`Pub`).
///
/// Provides generic functionality whilst deferring all serious cryptographic operations to `Pub`.
#[derive(Clone)]

View File

@@ -74,7 +74,7 @@ where
impl<'a, Pub, AggPub, Sig, AggSig> GenericSignatureSet<'a, Pub, AggPub, Sig, AggSig>
where
Pub: TPublicKey + Clone,
AggPub: TAggregatePublicKey + Clone,
AggPub: TAggregatePublicKey<Pub> + Clone,
Sig: TSignature<Pub> + Clone,
AggSig: TAggregateSignature<Pub, AggPub, Sig> + Clone,
{

View File

@@ -153,7 +153,19 @@ impl PartialEq for BlstAggregatePublicKey {
}
}
impl TAggregatePublicKey for BlstAggregatePublicKey {}
impl TAggregatePublicKey<blst_core::PublicKey> for BlstAggregatePublicKey {
fn to_public_key(&self) -> GenericPublicKey<blst_core::PublicKey> {
GenericPublicKey::from_point(self.0.to_public_key())
}
fn aggregate(pubkeys: &[GenericPublicKey<blst_core::PublicKey>]) -> Result<Self, Error> {
let pubkey_refs = pubkeys.iter().map(|pk| pk.point()).collect::<Vec<_>>();
// Public keys have already been checked for subgroup and infinity
let agg_pub = blst_core::AggregatePublicKey::aggregate(&pubkey_refs, false)?;
Ok(BlstAggregatePublicKey(agg_pub))
}
}
impl TSignature<blst_core::PublicKey> for blst_core::Signature {
fn serialize(&self) -> [u8; SIGNATURE_BYTES_LEN] {

View File

@@ -6,6 +6,7 @@ use crate::{
generic_signature::{TSignature, SIGNATURE_BYTES_LEN},
Error, Hash256, ZeroizeHash, INFINITY_PUBLIC_KEY, INFINITY_SIGNATURE,
};
/// Provides the externally-facing, core BLS types.
pub mod types {
pub use super::verify_signature_sets;
@@ -63,7 +64,15 @@ impl PartialEq for PublicKey {
#[derive(Clone)]
pub struct AggregatePublicKey([u8; PUBLIC_KEY_BYTES_LEN]);
impl TAggregatePublicKey for AggregatePublicKey {}
impl TAggregatePublicKey<PublicKey> for AggregatePublicKey {
fn to_public_key(&self) -> GenericPublicKey<PublicKey> {
GenericPublicKey::from_point(PublicKey(self.0))
}
fn aggregate(_pubkeys: &[GenericPublicKey<PublicKey>]) -> Result<Self, Error> {
Ok(Self(INFINITY_PUBLIC_KEY))
}
}
impl Eq for AggregatePublicKey {}

View File

@@ -86,7 +86,18 @@ impl TPublicKey for milagro::PublicKey {
}
}
impl TAggregatePublicKey for milagro::AggregatePublicKey {}
impl TAggregatePublicKey<milagro::PublicKey> for milagro::AggregatePublicKey {
fn to_public_key(&self) -> GenericPublicKey<milagro::PublicKey> {
GenericPublicKey::from_point(milagro::PublicKey {
point: self.point.clone(),
})
}
fn aggregate(pubkeys: &[GenericPublicKey<milagro::PublicKey>]) -> Result<Self, Error> {
let pubkey_refs = pubkeys.iter().map(|pk| pk.point()).collect::<Vec<_>>();
Ok(milagro::AggregatePublicKey::aggregate(&pubkey_refs)?)
}
}
impl TSignature<milagro::PublicKey> for milagro::Signature {
fn serialize(&self) -> [u8; SIGNATURE_BYTES_LEN] {

View File

@@ -79,6 +79,7 @@ impl From<BlstError> for Error {
/// Generic implementations which are only generally useful for docs.
pub mod generics {
pub use crate::generic_aggregate_public_key::GenericAggregatePublicKey;
pub use crate::generic_aggregate_signature::GenericAggregateSignature;
pub use crate::generic_keypair::GenericKeypair;
pub use crate::generic_public_key::GenericPublicKey;
@@ -102,6 +103,8 @@ macro_rules! define_mod {
pub type PublicKey = GenericPublicKey<bls_variant::PublicKey>;
pub type PublicKeyBytes = GenericPublicKeyBytes<bls_variant::PublicKey>;
pub type AggregatePublicKey =
GenericAggregatePublicKey<bls_variant::PublicKey, bls_variant::AggregatePublicKey>;
pub type Signature = GenericSignature<bls_variant::PublicKey, bls_variant::Signature>;
pub type AggregateSignature = GenericAggregateSignature<
bls_variant::PublicKey,