Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
testing/ef_tests/eth2.0-spec-tests
testing/ef_tests/consensus-spec-tests
target/
*.data
*.tar.gz
2 changes: 1 addition & 1 deletion .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
- uses: actions/checkout@v1
- name: Get latest version of stable Rust
run: rustup update stable
- name: Run eth2.0-spec-tests with blst, milagro and fake_crypto
- name: Run consensus-spec-tests with blst, milagro and fake_crypto
run: make test-ef
dockerfile-ubuntu:
name: dockerfile-ubuntu
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ run-ef-tests:
cargo test --release --manifest-path=$(EF_TESTS)/Cargo.toml --features "ef_tests"
cargo test --release --manifest-path=$(EF_TESTS)/Cargo.toml --features "ef_tests,fake_crypto"
cargo test --release --manifest-path=$(EF_TESTS)/Cargo.toml --features "ef_tests,milagro"
./$(EF_TESTS)/check_all_files_accessed.py $(EF_TESTS)/.accessed_file_log.txt $(EF_TESTS)/eth2.0-spec-tests
./$(EF_TESTS)/check_all_files_accessed.py $(EF_TESTS)/.accessed_file_log.txt $(EF_TESTS)/consensus-spec-tests

# Run the tests in the `beacon_chain` crate.
test-beacon-chain: test-beacon-chain-base test-beacon-chain-altair
Expand Down
6 changes: 3 additions & 3 deletions book/src/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ you can run them locally and avoid CI failures:

_The lighthouse test suite is quite extensive, running the whole suite may take 30+ minutes._

### Ethereum 2.0 Spec Tests
### Consensus Spec Tests

The
[ethereum/eth2.0-spec-tests](https://github.com/ethereum/eth2.0-spec-tests/)
[ethereum/consensus-spec-tests](https://github.com/ethereum/consensus-spec-tests/)
repository contains a large set of tests that verify Lighthouse behaviour
against the Ethereum Foundation specifications.

These tests are quite large (100's of MB) so they're only downloaded if you run
`$ make test-ef` (or anything that run it). You may want to avoid
`$ make test-ef` (or anything that runs it). You may want to avoid
downloading these tests if you're on a slow or metered Internet connection. CI
will require them to pass, though.
1 change: 1 addition & 0 deletions consensus/types/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ impl ChainSpec {
Self {
max_committees_per_slot: 4,
target_committee_size: 4,
churn_limit_quotient: 32,
shuffle_round_count: 10,
min_genesis_active_validator_count: 64,
min_genesis_time: 1578009600,
Expand Down
16 changes: 15 additions & 1 deletion crypto/bls/src/generic_aggregate_public_key.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use crate::{generic_public_key::GenericPublicKey, Error};
use crate::{
generic_public_key::{GenericPublicKey, TPublicKey},
Error,
};
use std::fmt::{self, Debug};
use std::marker::PhantomData;

/// Implemented on some struct from a BLS library so it may be used internally in this crate.
Expand Down Expand Up @@ -35,3 +39,13 @@ where
})
}
}

impl<Pub, AggPub> Debug for GenericAggregatePublicKey<Pub, AggPub>
where
AggPub: TAggregatePublicKey<Pub>,
Pub: TPublicKey,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.to_public_key())
}
}
14 changes: 14 additions & 0 deletions crypto/bls/src/generic_aggregate_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,20 @@ where
}
}

/// Wrapper for `fast_aggregate_verify` accepting `G2_POINT_AT_INFINITY` signature when
/// `pubkeys` is empty.
pub fn eth_fast_aggregate_verify(
&self,
msg: Hash256,
pubkeys: &[&GenericPublicKey<Pub>],
) -> bool {
if pubkeys.is_empty() && self.is_infinity() {
true
} else {
self.fast_aggregate_verify(msg, pubkeys)
}
}

/// Verify that `self` represents an aggregate signature where all `pubkeys` have signed their
/// corresponding message in `msgs`.
///
Expand Down
2 changes: 1 addition & 1 deletion testing/ef_tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/eth2.0-spec-tests
/consensus-spec-tests
.accessed_file_log.txt
4 changes: 2 additions & 2 deletions testing/ef_tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
TESTS_TAG := v1.1.0-beta.2
TESTS_TAG := v1.1.0-beta.4
TESTS = general minimal mainnet
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

REPO_NAME := eth2.0-spec-tests
REPO_NAME := consensus-spec-tests
OUTPUT_DIR := ./$(REPO_NAME)

BASE_URL := https://github.com/ethereum/$(REPO_NAME)/releases/download/$(TESTS_TAG)
Expand Down
8 changes: 4 additions & 4 deletions testing/ef_tests/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Ethereum 2.0 Specification Tests
# Consensus Specification Tests

This crate parses and executes the test vectors at [ethereum/eth2.0-spec-tests](https://github.com/ethereum/eth2.0-spec-tests).
This crate parses and executes the test vectors at [ethereum/consensus-spec-tests](https://github.com/ethereum/consensus-spec-tests).

Functionality is achieved only via the `$ cargo test --features ef_tests` command.

Expand All @@ -14,10 +14,10 @@ $ make
```

_Note: this may download hundreds of MB of compressed archives from the
[ethereum/eth2.0-spec-tests](https://github.com/ethereum/eth2.0-spec-tests/),
[ethereum/consensus-spec-tests](https://github.com/ethereum/consensus-spec-tests/),
which may expand into several GB of files._

If successful, you should now have the extracted tests in `./eth2.0-spec-tests`.
If successful, you should now have the extracted tests in `./consensus-spec-tests`.

Run them with:

Expand Down
15 changes: 4 additions & 11 deletions testing/ef_tests/check_all_files_accessed.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3

# The purpose of this script is to compare a list of file names that were accessed during testing
# against all the file names in the eth2.0-spec-tests repository. It then checks to see which files
# against all the file names in the consensus-spec-tests repository. It then checks to see which files
# were not accessed and returns an error if any non-intentionally-ignored files are detected.
#
# The ultimate goal is to detect any accidentally-missed spec tests.
Expand All @@ -12,20 +12,13 @@
# First argument should the path to a file which contains a list of accessed file names.
accessed_files_filename = sys.argv[1]

# Second argument should be the path to the eth2.0-spec-tests directory.
# Second argument should be the path to the consensus-spec-tests directory.
tests_dir_filename = sys.argv[2]

# If any of the file names found in the eth2.0-spec-tests directory *starts with* one of the
# If any of the file names found in the consensus-spec-tests directory *starts with* one of the
# following strings, we will assume they are to be ignored (i.e., we are purposefully *not* running
# the spec tests).
excluded_paths = [
# Configs from future phases
"tests/mainnet/config/custody_game.yaml",
"tests/mainnet/config/sharding.yaml",
"tests/mainnet/config/merge.yaml",
"tests/minimal/config/custody_game.yaml",
"tests/minimal/config/sharding.yaml",
"tests/minimal/config/merge.yaml",
# Merge tests
"tests/minimal/merge",
"tests/mainnet/merge",
Expand Down Expand Up @@ -53,7 +46,7 @@
]

def normalize_path(path):
return path.split("eth2.0-spec-tests/", )[1]
return path.split("consensus-spec-tests/", )[1]

# Determine the list of filenames which were accessed during tests.
passed = set()
Expand Down
4 changes: 4 additions & 0 deletions testing/ef_tests/src/cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use types::ForkName;

mod bls_aggregate_sigs;
mod bls_aggregate_verify;
mod bls_eth_aggregate_pubkeys;
mod bls_eth_fast_aggregate_verify;
mod bls_fast_aggregate_verify;
mod bls_sign_msg;
mod bls_verify_msg;
Expand All @@ -25,6 +27,8 @@ mod transition;

pub use bls_aggregate_sigs::*;
pub use bls_aggregate_verify::*;
pub use bls_eth_aggregate_pubkeys::*;
pub use bls_eth_fast_aggregate_verify::*;
pub use bls_fast_aggregate_verify::*;
pub use bls_sign_msg::*;
pub use bls_verify_msg::*;
Expand Down
4 changes: 4 additions & 0 deletions testing/ef_tests/src/cases/bls_aggregate_sigs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ pub struct BlsAggregateSigs {
impl BlsCase for BlsAggregateSigs {}

impl Case for BlsAggregateSigs {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let mut aggregate_signature = AggregateSignature::infinity();

Expand Down
4 changes: 4 additions & 0 deletions testing/ef_tests/src/cases/bls_aggregate_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub struct BlsAggregateVerify {
impl BlsCase for BlsAggregateVerify {}

impl Case for BlsAggregateVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let messages = self
.input
Expand Down
48 changes: 48 additions & 0 deletions testing/ef_tests/src/cases/bls_eth_aggregate_pubkeys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use bls::{AggregatePublicKey, PublicKeyBytes};
use serde_derive::Deserialize;

#[derive(Debug, Clone, Deserialize)]
pub struct BlsEthAggregatePubkeys {
pub input: Vec<PublicKeyBytes>,
pub output: Option<PublicKeyBytes>,
}

impl BlsCase for BlsEthAggregatePubkeys {}

impl Case for BlsEthAggregatePubkeys {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Altair
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let pubkeys_result = self
.input
.iter()
.map(|pkb| pkb.decompress())
.collect::<Result<Vec<_>, _>>();

let pubkeys = match pubkeys_result {
Ok(pubkeys) => pubkeys,
Err(bls::Error::InvalidInfinityPublicKey | bls::Error::BlstError(_))
if self.output.is_none() =>
{
return Ok(());
}
#[cfg(feature = "milagro")]
Err(bls::Error::MilagroError(_)) if self.output.is_none() => {
return Ok(());
}
Err(e) => return Err(Error::FailedToParseTest(format!("{:?}", e))),
};

let aggregate_pubkey =
AggregatePublicKey::aggregate(&pubkeys).map(|agg| agg.to_public_key());

let expected = self.output.as_ref().map(|pk| pk.decompress().unwrap());

compare_result::<_, bls::Error>(&aggregate_pubkey, &expected)
}
}
61 changes: 61 additions & 0 deletions testing/ef_tests/src/cases/bls_eth_fast_aggregate_verify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use std::convert::TryInto;
use types::Hash256;

#[derive(Debug, Clone, Deserialize)]
pub struct BlsEthFastAggregateVerifyInput {
pub pubkeys: Vec<PublicKeyBytes>,
#[serde(alias = "messages")]
pub message: String,
pub signature: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BlsEthFastAggregateVerify {
pub input: BlsEthFastAggregateVerifyInput,
pub output: bool,
}

impl BlsCase for BlsEthFastAggregateVerify {}

impl Case for BlsEthFastAggregateVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Altair
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let message = Hash256::from_slice(
&hex::decode(&self.input.message[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?,
);

let pubkeys_result = self
.input
.pubkeys
.iter()
.map(|pkb| pkb.try_into())
.collect::<Result<Vec<_>, _>>();

let pubkeys = match pubkeys_result {
Ok(pubkeys) => pubkeys,
Err(bls::Error::InvalidInfinityPublicKey) if !self.output => {
return Ok(());
}
Err(e) => return Err(Error::FailedToParseTest(format!("{:?}", e))),
};

let pubkey_refs = pubkeys.iter().collect::<Vec<_>>();

let signature_ok = hex::decode(&self.input.signature[2..])
.ok()
.and_then(|bytes: Vec<u8>| AggregateSignature::deserialize(&bytes).ok())
.map(|signature| signature.eth_fast_aggregate_verify(message, &pubkey_refs))
.unwrap_or(false);

compare_result::<bool, ()>(&Ok(signature_ok), &Some(self.output))
}
}
4 changes: 4 additions & 0 deletions testing/ef_tests/src/cases/bls_fast_aggregate_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ pub struct BlsFastAggregateVerify {
impl BlsCase for BlsFastAggregateVerify {}

impl Case for BlsFastAggregateVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let message = Hash256::from_slice(
&hex::decode(&self.input.message[2..])
Expand Down
4 changes: 4 additions & 0 deletions testing/ef_tests/src/cases/bls_sign_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pub struct BlsSign {
impl BlsCase for BlsSign {}

impl Case for BlsSign {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
// Convert private_key and message to required types
let sk = hex::decode(&self.input.privkey[2..])
Expand Down
4 changes: 4 additions & 0 deletions testing/ef_tests/src/cases/bls_verify_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ pub struct BlsVerify {
impl BlsCase for BlsVerify {}

impl Case for BlsVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let message = hex::decode(&self.input.message[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
Expand Down
1 change: 0 additions & 1 deletion testing/ef_tests/src/cases/ssz_generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ impl Case for SszGeneric {
let mut limit = parts[1];

// Test format is inconsistent, pretend the limit is 32 (arbitrary)
// https://github.com/ethereum/eth2.0-spec-tests
if limit == "no" {
limit = "32";
}
Expand Down
Loading