Refactor ef_tests for less code duplication
This commit is contained in:
parent
95b0df7087
commit
6fada99905
@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
mod bls_aggregate_pubkeys;
|
mod bls_aggregate_pubkeys;
|
||||||
mod bls_aggregate_sigs;
|
mod bls_aggregate_sigs;
|
||||||
@ -20,11 +21,28 @@ pub use operations_deposit::*;
|
|||||||
pub use ssz_generic::*;
|
pub use ssz_generic::*;
|
||||||
pub use ssz_static::*;
|
pub use ssz_static::*;
|
||||||
|
|
||||||
|
pub trait Case {
|
||||||
|
fn result(&self) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Cases<T> {
|
pub struct Cases<T> {
|
||||||
pub test_cases: Vec<T>,
|
pub test_cases: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> EfTest for Cases<T>
|
||||||
|
where
|
||||||
|
T: Case + Debug,
|
||||||
|
{
|
||||||
|
fn test_results(&self) -> Vec<CaseResult> {
|
||||||
|
self.test_cases
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, tc)| CaseResult::new(i, tc, tc.result()))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: YamlDecode> YamlDecode for Cases<T> {
|
impl<T: YamlDecode> YamlDecode for Cases<T> {
|
||||||
/// Decodes a YAML list of test cases
|
/// Decodes a YAML list of test cases
|
||||||
fn yaml_decode(yaml: &String) -> Result<Self, Error> {
|
fn yaml_decode(yaml: &String) -> Result<Self, Error> {
|
||||||
|
@ -2,7 +2,6 @@ use super::*;
|
|||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use bls::{AggregatePublicKey, PublicKey};
|
use bls::{AggregatePublicKey, PublicKey};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BlsAggregatePubkeys {
|
pub struct BlsAggregatePubkeys {
|
||||||
@ -16,36 +15,25 @@ impl YamlDecode for BlsAggregatePubkeys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<BlsAggregatePubkeys> {
|
impl Case for BlsAggregatePubkeys {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, tc)| {
|
|
||||||
let result = bls_add_pubkeys(&tc.input, &tc.output);
|
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a `aggregate_pubkeys` test case.
|
|
||||||
fn bls_add_pubkeys(inputs: &[String], output: &String) -> Result<(), Error> {
|
|
||||||
let mut aggregate_pubkey = AggregatePublicKey::new();
|
let mut aggregate_pubkey = AggregatePublicKey::new();
|
||||||
|
|
||||||
for key_str in inputs {
|
for key_str in &self.input {
|
||||||
let key =
|
let key = hex::decode(&key_str[2..])
|
||||||
hex::decode(&key_str[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let key = PublicKey::from_bytes(&key)
|
let key = PublicKey::from_bytes(&key)
|
||||||
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
|
|
||||||
aggregate_pubkey.add(&key);
|
aggregate_pubkey.add(&key);
|
||||||
}
|
}
|
||||||
|
|
||||||
let output_bytes =
|
let output_bytes = Some(
|
||||||
Some(hex::decode(&output[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?);
|
hex::decode(&self.output[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?,
|
||||||
|
);
|
||||||
let aggregate_pubkey = Ok(aggregate_pubkey.as_raw().as_bytes());
|
let aggregate_pubkey = Ok(aggregate_pubkey.as_raw().as_bytes());
|
||||||
|
|
||||||
compare_result::<Vec<u8>, Vec<u8>>(&aggregate_pubkey, &output_bytes)
|
compare_result::<Vec<u8>, Vec<u8>>(&aggregate_pubkey, &output_bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ use super::*;
|
|||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use bls::{AggregateSignature, Signature};
|
use bls::{AggregateSignature, Signature};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BlsAggregateSigs {
|
pub struct BlsAggregateSigs {
|
||||||
@ -16,36 +15,25 @@ impl YamlDecode for BlsAggregateSigs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<BlsAggregateSigs> {
|
impl Case for BlsAggregateSigs {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, tc)| {
|
|
||||||
let result = bls_add_signatures(&tc.input, &tc.output);
|
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a `aggregate_sigs` test case.
|
|
||||||
fn bls_add_signatures(inputs: &[String], output: &String) -> Result<(), Error> {
|
|
||||||
let mut aggregate_signature = AggregateSignature::new();
|
let mut aggregate_signature = AggregateSignature::new();
|
||||||
|
|
||||||
for key_str in inputs {
|
for key_str in &self.input {
|
||||||
let sig =
|
let sig = hex::decode(&key_str[2..])
|
||||||
hex::decode(&key_str[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let sig = Signature::from_bytes(&sig)
|
let sig = Signature::from_bytes(&sig)
|
||||||
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
|
|
||||||
aggregate_signature.add(&sig);
|
aggregate_signature.add(&sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
let output_bytes =
|
let output_bytes = Some(
|
||||||
Some(hex::decode(&output[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?);
|
hex::decode(&self.output[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?,
|
||||||
|
);
|
||||||
let aggregate_signature = Ok(aggregate_signature.as_bytes());
|
let aggregate_signature = Ok(aggregate_signature.as_bytes());
|
||||||
|
|
||||||
compare_result::<Vec<u8>, Vec<u8>>(&aggregate_signature, &output_bytes)
|
compare_result::<Vec<u8>, Vec<u8>>(&aggregate_signature, &output_bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ use super::*;
|
|||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use bls::{compress_g2, hash_on_g2};
|
use bls::{compress_g2, hash_on_g2};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BlsG2CompressedInput {
|
pub struct BlsG2CompressedInput {
|
||||||
@ -22,26 +21,13 @@ impl YamlDecode for BlsG2Compressed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<BlsG2Compressed> {
|
impl Case for BlsG2Compressed {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, tc)| {
|
|
||||||
let result = compressed_hash(&tc.input.message, &tc.input.domain, &tc.output);
|
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a `compressed hash to g2` test case.
|
|
||||||
fn compressed_hash(message: &String, domain: &String, output: &Vec<String>) -> Result<(), Error> {
|
|
||||||
// Convert message and domain to required types
|
// Convert message and domain to required types
|
||||||
let msg =
|
let msg = hex::decode(&self.input.message[2..])
|
||||||
hex::decode(&message[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let d = hex::decode(&domain[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
let d = hex::decode(&self.input.domain[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let d = bytes_to_u64(&d);
|
let d = bytes_to_u64(&d);
|
||||||
|
|
||||||
// Calculate the point and convert it to compressed bytes
|
// Calculate the point and convert it to compressed bytes
|
||||||
@ -49,13 +35,14 @@ fn compressed_hash(message: &String, domain: &String, output: &Vec<String>) -> R
|
|||||||
let point = compress_g2(&mut point);
|
let point = compress_g2(&mut point);
|
||||||
|
|
||||||
// Convert the output to one set of bytes
|
// Convert the output to one set of bytes
|
||||||
let mut decoded =
|
let mut decoded = hex::decode(&self.output[0][2..])
|
||||||
hex::decode(&output[0][2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let mut decoded_y =
|
let mut decoded_y = hex::decode(&self.output[1][2..])
|
||||||
hex::decode(&output[1][2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
decoded.append(&mut decoded_y);
|
decoded.append(&mut decoded_y);
|
||||||
|
|
||||||
compare_result::<Vec<u8>, Vec<u8>>(&Ok(point), &Some(decoded))
|
compare_result::<Vec<u8>, Vec<u8>>(&Ok(point), &Some(decoded))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a vector to u64 (from big endian)
|
// Converts a vector to u64 (from big endian)
|
||||||
|
@ -2,7 +2,6 @@ use super::*;
|
|||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use bls::hash_on_g2;
|
use bls::hash_on_g2;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BlsG2UncompressedInput {
|
pub struct BlsG2UncompressedInput {
|
||||||
@ -22,30 +21,13 @@ impl YamlDecode for BlsG2Uncompressed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<BlsG2Uncompressed> {
|
impl Case for BlsG2Uncompressed {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, tc)| {
|
|
||||||
let result = compressed_hash(&tc.input.message, &tc.input.domain, &tc.output);
|
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a `compressed hash to g2` test case.
|
|
||||||
fn compressed_hash(
|
|
||||||
message: &String,
|
|
||||||
domain: &String,
|
|
||||||
output: &Vec<Vec<String>>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
// Convert message and domain to required types
|
// Convert message and domain to required types
|
||||||
let msg =
|
let msg = hex::decode(&self.input.message[2..])
|
||||||
hex::decode(&message[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let d = hex::decode(&domain[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
let d = hex::decode(&self.input.domain[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let d = bytes_to_u64(&d);
|
let d = bytes_to_u64(&d);
|
||||||
|
|
||||||
// Calculate the point and convert it to compressed bytes
|
// Calculate the point and convert it to compressed bytes
|
||||||
@ -60,7 +42,7 @@ fn compressed_hash(
|
|||||||
|
|
||||||
// Convert the output to one set of bytes (x.a, x.b, y.a, y.b, z.a, z.b)
|
// Convert the output to one set of bytes (x.a, x.b, y.a, y.b, z.a, z.b)
|
||||||
let mut decoded: Vec<u8> = vec![];
|
let mut decoded: Vec<u8> = vec![];
|
||||||
for coordinate in output {
|
for coordinate in &self.output {
|
||||||
let mut decoded_part = hex::decode(&coordinate[0][2..])
|
let mut decoded_part = hex::decode(&coordinate[0][2..])
|
||||||
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
decoded.append(&mut decoded_part);
|
decoded.append(&mut decoded_part);
|
||||||
@ -70,6 +52,7 @@ fn compressed_hash(
|
|||||||
}
|
}
|
||||||
|
|
||||||
compare_result::<Vec<u8>, Vec<u8>>(&Ok(point_bytes.to_vec()), &Some(decoded))
|
compare_result::<Vec<u8>, Vec<u8>>(&Ok(point_bytes.to_vec()), &Some(decoded))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a vector to u64 (from big endian)
|
// Converts a vector to u64 (from big endian)
|
||||||
|
@ -2,7 +2,6 @@ use super::*;
|
|||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use bls::{PublicKey, SecretKey};
|
use bls::{PublicKey, SecretKey};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BlsPrivToPub {
|
pub struct BlsPrivToPub {
|
||||||
@ -16,22 +15,10 @@ impl YamlDecode for BlsPrivToPub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<BlsPrivToPub> {
|
impl Case for BlsPrivToPub {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
let secret = &self.input;
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, tc)| {
|
|
||||||
let result = secret_to_public(&tc.input, &tc.output);
|
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a `Private key to public key` test case.
|
|
||||||
fn secret_to_public(secret: &String, output: &String) -> Result<(), Error> {
|
|
||||||
// Convert message and domain to required types
|
// Convert message and domain to required types
|
||||||
let mut sk =
|
let mut sk =
|
||||||
hex::decode(&secret[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
hex::decode(&secret[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
@ -39,10 +26,11 @@ fn secret_to_public(secret: &String, output: &String) -> Result<(), Error> {
|
|||||||
let sk = SecretKey::from_bytes(&sk).unwrap();
|
let sk = SecretKey::from_bytes(&sk).unwrap();
|
||||||
let pk = PublicKey::from_secret_key(&sk);
|
let pk = PublicKey::from_secret_key(&sk);
|
||||||
|
|
||||||
let decoded =
|
let decoded = hex::decode(&self.output[2..])
|
||||||
hex::decode(&output[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
|
|
||||||
compare_result::<Vec<u8>, Vec<u8>>(&Ok(pk.as_raw().as_bytes()), &Some(decoded))
|
compare_result::<Vec<u8>, Vec<u8>>(&Ok(pk.as_raw().as_bytes()), &Some(decoded))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase the size of an array to 48 bytes
|
// Increase the size of an array to 48 bytes
|
||||||
|
@ -2,7 +2,6 @@ use super::*;
|
|||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use bls::{SecretKey, Signature};
|
use bls::{SecretKey, Signature};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct BlsSignInput {
|
pub struct BlsSignInput {
|
||||||
@ -23,49 +22,27 @@ impl YamlDecode for BlsSign {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<BlsSign> {
|
impl Case for BlsSign {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, tc)| {
|
|
||||||
let result = sign_msg(
|
|
||||||
&tc.input.privkey,
|
|
||||||
&tc.input.message,
|
|
||||||
&tc.input.domain,
|
|
||||||
&tc.output,
|
|
||||||
);
|
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a `compressed hash to g2` test case.
|
|
||||||
fn sign_msg(
|
|
||||||
private_key: &String,
|
|
||||||
message: &String,
|
|
||||||
domain: &String,
|
|
||||||
output: &String,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
// Convert private_key, message and domain to required types
|
// Convert private_key, message and domain to required types
|
||||||
let mut sk =
|
let mut sk = hex::decode(&self.input.privkey[2..])
|
||||||
hex::decode(&private_key[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
pad_to_48(&mut sk);
|
pad_to_48(&mut sk);
|
||||||
let sk = SecretKey::from_bytes(&sk).unwrap();
|
let sk = SecretKey::from_bytes(&sk).unwrap();
|
||||||
let msg =
|
let msg = hex::decode(&self.input.message[2..])
|
||||||
hex::decode(&message[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let d = hex::decode(&domain[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
let d = hex::decode(&self.input.domain[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
let d = bytes_to_u64(&d);
|
let d = bytes_to_u64(&d);
|
||||||
|
|
||||||
let signature = Signature::new(&msg, d, &sk);
|
let signature = Signature::new(&msg, d, &sk);
|
||||||
|
|
||||||
// Convert the output to one set of bytes
|
// Convert the output to one set of bytes
|
||||||
let decoded =
|
let decoded = hex::decode(&self.output[2..])
|
||||||
hex::decode(&output[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
|
||||||
|
|
||||||
compare_result::<Vec<u8>, Vec<u8>>(&Ok(signature.as_bytes()), &Some(decoded))
|
compare_result::<Vec<u8>, Vec<u8>>(&Ok(signature.as_bytes()), &Some(decoded))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a vector to u64 (from big endian)
|
// Converts a vector to u64 (from big endian)
|
||||||
|
@ -18,6 +18,7 @@ impl<E: EthSpec> YamlDecode for OperationsDeposit<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
impl<T: EthSpec> EfTest for Cases<OperationsDeposit<T>> {
|
impl<T: EthSpec> EfTest for Cases<OperationsDeposit<T>> {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
||||||
self.test_cases
|
self.test_cases
|
||||||
@ -32,3 +33,4 @@ impl<T: EthSpec> EfTest for Cases<OperationsDeposit<T>> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -4,7 +4,6 @@ use ethereum_types::{U128, U256};
|
|||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use ssz::Decode;
|
use ssz::Decode;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct SszGeneric {
|
pub struct SszGeneric {
|
||||||
@ -21,23 +20,19 @@ impl YamlDecode for SszGeneric {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<SszGeneric> {
|
impl Case for SszGeneric {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
if let Some(ssz) = &self.ssz {
|
||||||
.iter()
|
match self.type_name.as_ref() {
|
||||||
.enumerate()
|
"uint8" => ssz_generic_test::<u8>(self.valid, ssz, &self.value),
|
||||||
.map(|(i, tc)| {
|
"uint16" => ssz_generic_test::<u16>(self.valid, ssz, &self.value),
|
||||||
let result = if let Some(ssz) = &tc.ssz {
|
"uint32" => ssz_generic_test::<u32>(self.valid, ssz, &self.value),
|
||||||
match tc.type_name.as_ref() {
|
"uint64" => ssz_generic_test::<u64>(self.valid, ssz, &self.value),
|
||||||
"uint8" => ssz_generic_test::<u8>(tc.valid, ssz, &tc.value),
|
"uint128" => ssz_generic_test::<U128>(self.valid, ssz, &self.value),
|
||||||
"uint16" => ssz_generic_test::<u16>(tc.valid, ssz, &tc.value),
|
"uint256" => ssz_generic_test::<U256>(self.valid, ssz, &self.value),
|
||||||
"uint32" => ssz_generic_test::<u32>(tc.valid, ssz, &tc.value),
|
|
||||||
"uint64" => ssz_generic_test::<u64>(tc.valid, ssz, &tc.value),
|
|
||||||
"uint128" => ssz_generic_test::<U128>(tc.valid, ssz, &tc.value),
|
|
||||||
"uint256" => ssz_generic_test::<U256>(tc.valid, ssz, &tc.value),
|
|
||||||
_ => Err(Error::FailedToParseTest(format!(
|
_ => Err(Error::FailedToParseTest(format!(
|
||||||
"Unknown type: {}",
|
"Unknown type: {}",
|
||||||
tc.type_name
|
self.type_name
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -45,11 +40,7 @@ impl EfTest for Cases<SszGeneric> {
|
|||||||
//
|
//
|
||||||
// See: https://github.com/ethereum/eth2.0-specs/issues/1079
|
// See: https://github.com/ethereum/eth2.0-specs/issues/1079
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
}
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::case_result::compare_result;
|
use crate::case_result::compare_result;
|
||||||
use cached_tree_hash::{CachedTreeHash, TreeHashCache};
|
use cached_tree_hash::{CachedTreeHash, TreeHashCache};
|
||||||
use rayon::prelude::*;
|
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use ssz::{Decode, Encode, ssz_encode};
|
use ssz::{Decode, Encode};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
use types::{
|
use types::{
|
||||||
test_utils::{SeedableRng, TestRandom, XorShiftRng},
|
test_utils::{SeedableRng, TestRandom, XorShiftRng},
|
||||||
@ -15,12 +15,14 @@ use types::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct SszStatic {
|
pub struct SszStatic<E> {
|
||||||
pub type_name: String,
|
pub type_name: String,
|
||||||
pub serialized: String,
|
pub serialized: String,
|
||||||
pub root: String,
|
pub root: String,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub raw_yaml: String,
|
pub raw_yaml: String,
|
||||||
|
#[serde(skip, default)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
@ -28,9 +30,9 @@ pub struct Value<T> {
|
|||||||
value: T,
|
value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl YamlDecode for SszStatic {
|
impl<E> YamlDecode for SszStatic<E> {
|
||||||
fn yaml_decode(yaml: &String) -> Result<Self, Error> {
|
fn yaml_decode(yaml: &String) -> Result<Self, Error> {
|
||||||
let mut ssz_static: SszStatic = serde_yaml::from_str(&yaml.as_str()).unwrap();
|
let mut ssz_static: SszStatic<E> = serde_yaml::from_str(&yaml.as_str()).unwrap();
|
||||||
|
|
||||||
ssz_static.raw_yaml = yaml.clone();
|
ssz_static.raw_yaml = yaml.clone();
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ impl YamlDecode for SszStatic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SszStatic {
|
impl<E> SszStatic<E> {
|
||||||
fn value<T: serde::de::DeserializeOwned>(&self) -> Result<T, Error> {
|
fn value<T: serde::de::DeserializeOwned>(&self) -> Result<T, Error> {
|
||||||
let wrapper: Value<T> = serde_yaml::from_str(&self.raw_yaml.as_str()).map_err(|e| {
|
let wrapper: Value<T> = serde_yaml::from_str(&self.raw_yaml.as_str()).map_err(|e| {
|
||||||
Error::FailedToParseTest(format!("Unable to parse {} YAML: {:?}", self.type_name, e))
|
Error::FailedToParseTest(format!("Unable to parse {} YAML: {:?}", self.type_name, e))
|
||||||
@ -48,48 +50,40 @@ impl SszStatic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EfTest for Cases<SszStatic> {
|
impl<E: EthSpec> Case for SszStatic<E> {
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
|
fn result(&self) -> Result<(), Error> {
|
||||||
self.test_cases
|
match self.type_name.as_ref() {
|
||||||
.par_iter()
|
"Fork" => ssz_static_test::<Fork, E>(self),
|
||||||
.enumerate()
|
"Crosslink" => ssz_static_test::<Crosslink, E>(self),
|
||||||
.map(|(i, tc)| {
|
"Eth1Data" => ssz_static_test::<Eth1Data, E>(self),
|
||||||
let result = match tc.type_name.as_ref() {
|
"AttestationData" => ssz_static_test::<AttestationData, E>(self),
|
||||||
"Fork" => ssz_static_test::<Fork>(tc),
|
|
||||||
"Crosslink" => ssz_static_test::<Crosslink>(tc),
|
|
||||||
"Eth1Data" => ssz_static_test::<Eth1Data>(tc),
|
|
||||||
"AttestationData" => ssz_static_test::<AttestationData>(tc),
|
|
||||||
"AttestationDataAndCustodyBit" => {
|
"AttestationDataAndCustodyBit" => {
|
||||||
ssz_static_test::<AttestationDataAndCustodyBit>(tc)
|
ssz_static_test::<AttestationDataAndCustodyBit, E>(self)
|
||||||
}
|
}
|
||||||
"IndexedAttestation" => ssz_static_test::<IndexedAttestation>(tc),
|
"IndexedAttestation" => ssz_static_test::<IndexedAttestation, E>(self),
|
||||||
"DepositData" => ssz_static_test::<DepositData>(tc),
|
"DepositData" => ssz_static_test::<DepositData, E>(self),
|
||||||
"BeaconBlockHeader" => ssz_static_test::<BeaconBlockHeader>(tc),
|
"BeaconBlockHeader" => ssz_static_test::<BeaconBlockHeader, E>(self),
|
||||||
"Validator" => ssz_static_test::<Validator>(tc),
|
"Validator" => ssz_static_test::<Validator, E>(self),
|
||||||
"PendingAttestation" => ssz_static_test::<PendingAttestation>(tc),
|
"PendingAttestation" => ssz_static_test::<PendingAttestation, E>(self),
|
||||||
"HistoricalBatch" => ssz_static_test::<HistoricalBatch<E>>(tc),
|
"HistoricalBatch" => ssz_static_test::<HistoricalBatch<E>, E>(self),
|
||||||
"ProposerSlashing" => ssz_static_test::<ProposerSlashing>(tc),
|
"ProposerSlashing" => ssz_static_test::<ProposerSlashing, E>(self),
|
||||||
"AttesterSlashing" => ssz_static_test::<AttesterSlashing>(tc),
|
"AttesterSlashing" => ssz_static_test::<AttesterSlashing, E>(self),
|
||||||
"Attestation" => ssz_static_test::<Attestation>(tc),
|
"Attestation" => ssz_static_test::<Attestation, E>(self),
|
||||||
"Deposit" => ssz_static_test::<Deposit>(tc),
|
"Deposit" => ssz_static_test::<Deposit, E>(self),
|
||||||
"VoluntaryExit" => ssz_static_test::<VoluntaryExit>(tc),
|
"VoluntaryExit" => ssz_static_test::<VoluntaryExit, E>(self),
|
||||||
"Transfer" => ssz_static_test::<Transfer>(tc),
|
"Transfer" => ssz_static_test::<Transfer, E>(self),
|
||||||
"BeaconBlockBody" => ssz_static_test::<BeaconBlockBody>(tc),
|
"BeaconBlockBody" => ssz_static_test::<BeaconBlockBody, E>(self),
|
||||||
"BeaconBlock" => ssz_static_test::<BeaconBlock>(tc),
|
"BeaconBlock" => ssz_static_test::<BeaconBlock, E>(self),
|
||||||
"BeaconState" => ssz_static_test::<BeaconState<E>>(tc),
|
"BeaconState" => ssz_static_test::<BeaconState<E>, E>(self),
|
||||||
_ => Err(Error::FailedToParseTest(format!(
|
_ => Err(Error::FailedToParseTest(format!(
|
||||||
"Unknown type: {}",
|
"Unknown type: {}",
|
||||||
tc.type_name
|
self.type_name
|
||||||
))),
|
))),
|
||||||
};
|
}
|
||||||
|
|
||||||
CaseResult::new(i, tc, result)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ssz_static_test<T>(tc: &SszStatic) -> Result<(), Error>
|
fn ssz_static_test<T, E: EthSpec>(tc: &SszStatic<E>) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: Clone
|
T: Clone
|
||||||
+ Decode
|
+ Decode
|
||||||
@ -111,7 +105,7 @@ where
|
|||||||
// Verify we can encode the result back into original ssz bytes
|
// Verify we can encode the result back into original ssz bytes
|
||||||
let decoded = decode_result.unwrap();
|
let decoded = decode_result.unwrap();
|
||||||
let encoded_result = decoded.as_ssz_bytes();
|
let encoded_result = decoded.as_ssz_bytes();
|
||||||
compare_result::<Vec<u8>, Error>(&Ok(encoded_result), &Some(ssz));
|
compare_result::<Vec<u8>, Error>(&Ok(encoded_result), &Some(ssz))?;
|
||||||
|
|
||||||
// Verify the TreeHash root of the decoded struct matches the test.
|
// Verify the TreeHash root of the decoded struct matches the test.
|
||||||
let expected_root =
|
let expected_root =
|
||||||
|
@ -6,7 +6,6 @@ use crate::yaml_decode::{yaml_split_header_and_cases, YamlDecode};
|
|||||||
use crate::EfTest;
|
use crate::EfTest;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use std::{fs::File, io::prelude::*, path::PathBuf};
|
use std::{fs::File, io::prelude::*, path::PathBuf};
|
||||||
use types::EthSpec;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Doc {
|
pub struct Doc {
|
||||||
@ -39,31 +38,27 @@ impl Doc {
|
|||||||
header.handler.as_ref(),
|
header.handler.as_ref(),
|
||||||
header.config.as_ref(),
|
header.config.as_ref(),
|
||||||
) {
|
) {
|
||||||
("ssz", "uint", _) => run_test::<SszGeneric, MainnetEthSpec>(self),
|
("ssz", "uint", _) => run_test::<SszGeneric>(self),
|
||||||
("ssz", "static", "minimal") => run_test::<SszStatic, MinimalEthSpec>(self),
|
("ssz", "static", "minimal") => run_test::<SszStatic<MinimalEthSpec>>(self),
|
||||||
("ssz", "static", "mainnet") => run_test::<SszStatic, MainnetEthSpec>(self),
|
("ssz", "static", "mainnet") => run_test::<SszStatic<MainnetEthSpec>>(self),
|
||||||
("bls", "aggregate_pubkeys", "mainnet") => {
|
("bls", "aggregate_pubkeys", "mainnet") => run_test::<BlsAggregatePubkeys>(self),
|
||||||
run_test::<BlsAggregatePubkeys, MainnetEthSpec>(self)
|
("bls", "aggregate_sigs", "mainnet") => run_test::<BlsAggregateSigs>(self),
|
||||||
}
|
("bls", "msg_hash_compressed", "mainnet") => run_test::<BlsG2Compressed>(self),
|
||||||
("bls", "aggregate_sigs", "mainnet") => {
|
|
||||||
run_test::<BlsAggregateSigs, MainnetEthSpec>(self)
|
|
||||||
}
|
|
||||||
("bls", "msg_hash_compressed", "mainnet") => {
|
|
||||||
run_test::<BlsG2Compressed, MainnetEthSpec>(self)
|
|
||||||
}
|
|
||||||
// Note this test fails due to a difference in our internal representations. It does
|
// Note this test fails due to a difference in our internal representations. It does
|
||||||
// not effect verification or external representation.
|
// not effect verification or external representation.
|
||||||
//
|
//
|
||||||
// It is skipped.
|
// It is skipped.
|
||||||
("bls", "msg_hash_uncompressed", "mainnet") => vec![],
|
("bls", "msg_hash_uncompressed", "mainnet") => vec![],
|
||||||
("bls", "priv_to_pub", "mainnet") => run_test::<BlsPrivToPub, MainnetEthSpec>(self),
|
("bls", "priv_to_pub", "mainnet") => run_test::<BlsPrivToPub>(self),
|
||||||
("bls", "sign_msg", "mainnet") => run_test::<BlsSign, MainnetEthSpec>(self),
|
("bls", "sign_msg", "mainnet") => run_test::<BlsSign>(self),
|
||||||
|
/*
|
||||||
("operations", "deposit", "mainnet") => {
|
("operations", "deposit", "mainnet") => {
|
||||||
run_test::<OperationsDeposit<MainnetEthSpec>, MainnetEthSpec>(self)
|
run_test::<OperationsDeposit<MainnetEthSpec>>(self)
|
||||||
}
|
}
|
||||||
("operations", "deposit", "minimal") => {
|
("operations", "deposit", "minimal") => {
|
||||||
run_test::<OperationsDeposit<MinimalEthSpec>, MinimalEthSpec>(self)
|
run_test::<OperationsDeposit<MinimalEthSpec>>(self)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
(runner, handler, config) => panic!(
|
(runner, handler, config) => panic!(
|
||||||
"No implementation for runner: \"{}\", handler: \"{}\", config: \"{}\"",
|
"No implementation for runner: \"{}\", handler: \"{}\", config: \"{}\"",
|
||||||
runner, handler, config
|
runner, handler, config
|
||||||
@ -84,7 +79,7 @@ impl Doc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_test<T, E: EthSpec>(doc: &Doc) -> Vec<CaseResult>
|
pub fn run_test<T>(doc: &Doc) -> Vec<CaseResult>
|
||||||
where
|
where
|
||||||
Cases<T>: EfTest + YamlDecode,
|
Cases<T>: EfTest + YamlDecode,
|
||||||
{
|
{
|
||||||
@ -94,7 +89,7 @@ where
|
|||||||
// Pass only the "test_cases" YAML string to `yaml_decode`.
|
// Pass only the "test_cases" YAML string to `yaml_decode`.
|
||||||
let test_cases: Cases<T> = Cases::yaml_decode(&doc.cases_yaml).unwrap();
|
let test_cases: Cases<T> = Cases::yaml_decode(&doc.cases_yaml).unwrap();
|
||||||
|
|
||||||
test_cases.test_results::<E>()
|
test_cases.test_results()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_failures(doc: &Doc, results: &[CaseResult]) {
|
pub fn print_failures(doc: &Doc, results: &[CaseResult]) {
|
||||||
|
@ -17,5 +17,5 @@ mod yaml_decode;
|
|||||||
/// Foundation testing format.
|
/// Foundation testing format.
|
||||||
pub trait EfTest {
|
pub trait EfTest {
|
||||||
/// Returns the results of executing one or more tests.
|
/// Returns the results of executing one or more tests.
|
||||||
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult>;
|
fn test_results(&self) -> Vec<CaseResult>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user