Support multiple BLS implementations (#1335)

## Issue Addressed

NA

## Proposed Changes

- Refactor the `bls` crate to support multiple BLS "backends" (e.g., milagro, blst, etc).
- Removes some duplicate, unused code in `common/rest_types/src/validator.rs`.
- Removes the old "upgrade legacy keypairs" functionality (these were unencrypted keys that haven't been supported for a few testnets, no one should be using them anymore).

## Additional Info

Most of the files changed are just inconsequential changes to function names.

## TODO

- [x] Optimization levels
- [x] Infinity point: https://github.com/supranational/blst/issues/11
- [x] Ensure milagro *and* blst are tested via CI
- [x] What to do with unsafe code?
- [x] Test infinity point in signature sets
This commit is contained in:
Paul Hauner
2020-07-25 02:03:18 +00:00
parent 21bcc8848d
commit b73c497be2
117 changed files with 3009 additions and 2463 deletions

View File

@@ -521,7 +521,7 @@ pub fn verify_attestation_signature<T: BeaconChainTypes>(
let _signature_verification_timer =
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_SIGNATURE_TIMES);
if signature_set.is_valid() {
if signature_set.verify() {
Ok(())
} else {
Err(Error::InvalidSignature)
@@ -589,7 +589,7 @@ pub fn verify_signed_aggregate_signatures<T: BeaconChainTypes>(
.map_err(BeaconChainError::SignatureSetError)?,
];
Ok(verify_signature_sets(signature_sets))
Ok(verify_signature_sets(signature_sets.iter()))
}
/// Assists in readability.

View File

@@ -862,7 +862,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
root: target_root,
},
},
signature: AggregateSignature::empty_signature(),
signature: AggregateSignature::empty(),
})
}
@@ -1654,7 +1654,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
},
},
// The block is not signed here, that is the task of a validator client.
signature: Signature::empty_signature(),
signature: Signature::empty(),
};
per_block_processing(

View File

@@ -666,7 +666,7 @@ fn genesis_block<T: EthSpec>(
message: BeaconBlock::empty(&spec),
// Empty signature, which should NEVER be read. This isn't to-spec, but makes the genesis
// block consistent with every other block.
signature: Signature::empty_signature(),
signature: Signature::empty(),
};
genesis_block.message.state_root = genesis_state
.update_tree_hash_cache()

View File

@@ -6,7 +6,6 @@ use crate::observed_attesters::Error as ObservedAttestersError;
use crate::observed_block_producers::Error as ObservedBlockProducersError;
use operation_pool::OpPoolError;
use safe_arith::ArithError;
use ssz::DecodeError;
use ssz_types::Error as SszTypesError;
use state_processing::{
block_signature_verifier::Error as BlockSignatureVerifierError,
@@ -69,7 +68,7 @@ pub enum BeaconChainError {
AttestationCacheLockTimeout,
ValidatorPubkeyCacheLockTimeout,
IncorrectStateForAttestation(RelativeEpochError),
InvalidValidatorPubkeyBytes(DecodeError),
InvalidValidatorPubkeyBytes(bls::Error),
ValidatorPubkeyCacheIncomplete(usize),
SignatureSetError(SignatureSetError),
BlockSignatureVerifierError(state_processing::block_signature_verifier::Error),

View File

@@ -99,7 +99,7 @@ mod test {
use super::*;
use types::{
test_utils::{generate_deterministic_keypair, TestingBeaconStateBuilder},
BeaconBlock, Epoch, MainnetEthSpec, Signature, SignedBeaconBlock, Slot,
BeaconBlock, Epoch, MainnetEthSpec, SignedBeaconBlock, Slot,
};
const CACHE_SIZE: usize = 4;
@@ -115,7 +115,9 @@ mod test {
beacon_state_root: Hash256::from_low_u64_be(i),
beacon_block: SignedBeaconBlock {
message: BeaconBlock::empty(&spec),
signature: Signature::new(&[42], &generate_deterministic_keypair(0).sk),
signature: generate_deterministic_keypair(0)
.sk
.sign(Hash256::from_low_u64_be(42)),
},
beacon_block_root: Hash256::from_low_u64_be(i),
}

View File

@@ -23,8 +23,8 @@ use tempfile::{tempdir, TempDir};
use tree_hash::TreeHash;
use types::{
AggregateSignature, Attestation, BeaconState, BeaconStateHash, ChainSpec, Domain, EthSpec,
Hash256, Keypair, SecretKey, SelectionProof, Signature, SignedAggregateAndProof,
SignedBeaconBlock, SignedBeaconBlockHash, SignedRoot, Slot, SubnetId,
Hash256, Keypair, SecretKey, SelectionProof, SignedAggregateAndProof, SignedBeaconBlock,
SignedBeaconBlockHash, SignedRoot, Slot, SubnetId,
};
pub use types::test_utils::generate_deterministic_keypairs;
@@ -515,7 +515,7 @@ where
self.spec
.get_domain(epoch, Domain::Randao, fork, state.genesis_validators_root);
let message = epoch.signing_root(domain);
Signature::new(message.as_bytes(), sk)
sk.sign(message)
};
let (block, state) = self
@@ -586,12 +586,9 @@ where
let message = attestation.data.signing_root(domain);
let mut agg_sig = AggregateSignature::new();
let mut agg_sig = AggregateSignature::infinity();
agg_sig.add(&Signature::new(
message.as_bytes(),
self.get_sk(*validator_index),
));
agg_sig.add_assign(&self.get_sk(*validator_index).sign(message));
agg_sig
};

View File

@@ -140,6 +140,7 @@ struct ValidatorPubkeyCacheFile(File);
enum Error {
Io(io::Error),
Ssz(DecodeError),
PubkeyDecode(bls::Error),
/// The file read from disk does not have a contiguous list of validator public keys. The file
/// has become corrupted.
InconsistentIndex {
@@ -200,7 +201,7 @@ impl ValidatorPubkeyCacheFile {
let expected = last.map(|n| n + 1);
if expected.map_or(true, |expected| index == expected) {
last = Some(index);
pubkeys.push((&pubkey).try_into().map_err(Error::Ssz)?);
pubkeys.push((&pubkey).try_into().map_err(Error::PubkeyDecode)?);
indices.insert(pubkey, index);
} else {
return Err(Error::InconsistentIndex {