Merged master and fixed merge conflicts with Config updates.

This commit is contained in:
Luke Anderson
2019-03-25 17:03:17 +11:00
25 changed files with 1259 additions and 448 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -15,12 +15,10 @@ pub struct TestDoc {
pub title: String,
pub summary: String,
pub fork: String,
pub version: String,
pub test_cases: Vec<TestCase>,
}
#[test]
#[ignore]
fn yaml() {
use serde_yaml;
use std::{fs::File, io::prelude::*, path::PathBuf};

View File

@@ -10,6 +10,7 @@ boolean-bitfield = { path = "../utils/boolean-bitfield" }
dirs = "1.0"
ethereum-types = "0.5"
hashing = { path = "../utils/hashing" }
hex = "0.3"
honey-badger-split = { path = "../utils/honey-badger-split" }
int_to_bytes = { path = "../utils/int_to_bytes" }
log = "0.4"

View File

@@ -2,6 +2,7 @@ use crate::*;
use bls::Signature;
use int_to_bytes::int_to_bytes4;
use serde_derive::Deserialize;
use test_utils::u8_from_hex_str;
const GWEI: u64 = 1_000_000_000;
@@ -57,6 +58,7 @@ pub struct ChainSpec {
pub far_future_epoch: Epoch,
pub zero_hash: Hash256,
pub empty_signature: Signature,
#[serde(deserialize_with = "u8_from_hex_str")]
pub bls_withdrawal_prefix_byte: u8,
/*

View File

@@ -1,4 +1,7 @@
use crate::{test_utils::TestRandom, ChainSpec, Epoch};
use crate::{
test_utils::{fork_from_hex_str, TestRandom},
ChainSpec, Epoch,
};
use int_to_bytes::int_to_bytes4;
use rand::RngCore;
use serde_derive::{Deserialize, Serialize};
@@ -12,7 +15,9 @@ use test_random_derive::TestRandom;
Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
)]
pub struct Fork {
#[serde(deserialize_with = "fork_from_hex_str")]
pub previous_version: [u8; 4],
#[serde(deserialize_with = "fork_from_hex_str")]
pub current_version: [u8; 4],
pub epoch: Epoch,
}

View File

@@ -2,6 +2,7 @@
mod macros;
mod generate_deterministic_keypairs;
mod keypairs_file;
mod serde_utils;
mod test_random;
mod testing_attestation_builder;
mod testing_attestation_data_builder;
@@ -17,6 +18,7 @@ mod testing_voluntary_exit_builder;
pub use generate_deterministic_keypairs::generate_deterministic_keypairs;
pub use keypairs_file::KeypairsFile;
pub use rand::{prng::XorShiftRng, SeedableRng};
pub use serde_utils::{fork_from_hex_str, u8_from_hex_str};
pub use test_random::TestRandom;
pub use testing_attestation_builder::TestingAttestationBuilder;
pub use testing_attestation_data_builder::TestingAttestationDataBuilder;

View File

@@ -0,0 +1,28 @@
use serde::de::Error;
use serde::{Deserialize, Deserializer};
pub fn u8_from_hex_str<'de, D>(deserializer: D) -> Result<u8, D::Error>
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
u8::from_str_radix(&s.as_str()[2..], 16).map_err(D::Error::custom)
}
pub fn fork_from_hex_str<'de, D>(deserializer: D) -> Result<[u8; 4], D::Error>
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
let mut array = [0 as u8; 4];
let decoded: Vec<u8> = hex::decode(&s.as_str()[2..]).map_err(D::Error::custom)?;
for (i, item) in array.iter_mut().enumerate() {
if i > decoded.len() {
break;
}
*item = decoded[i];
}
Ok(array)
}

View File

@@ -14,4 +14,8 @@ impl Keypair {
let pk = PublicKey::from_secret_key(&sk);
Keypair { sk, pk }
}
pub fn identifier(&self) -> String {
self.pk.concatenated_hex_id()
}
}

View File

@@ -8,13 +8,14 @@ impl<'de> Visitor<'de> for HexVisitor {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a hex string (without 0x prefix)")
formatter.write_str("a hex string (irrelevant of prefix)")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(hex::decode(value).map_err(|e| de::Error::custom(format!("invalid hex ({:?})", e)))?)
Ok(hex::decode(value.trim_start_matches("0x"))
.map_err(|e| de::Error::custom(format!("invalid hex ({:?})", e)))?)
}
}

View File

@@ -13,27 +13,35 @@ use ssz::{
/// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ
/// serialization).
#[derive(Debug, PartialEq, Clone, Eq)]
pub struct Signature(RawSignature);
pub struct Signature {
signature: RawSignature,
is_empty: bool,
}
impl Signature {
/// Instantiate a new Signature from a message and a SecretKey.
pub fn new(msg: &[u8], domain: u64, sk: &SecretKey) -> Self {
Signature(RawSignature::new(msg, domain, sk.as_raw()))
Signature {
signature: RawSignature::new(msg, domain, sk.as_raw()),
is_empty: false,
}
}
/// Instantiate a new Signature from a message and a SecretKey, where the message has already
/// been hashed.
pub fn new_hashed(x_real_hashed: &[u8], x_imaginary_hashed: &[u8], sk: &SecretKey) -> Self {
Signature(RawSignature::new_hashed(
x_real_hashed,
x_imaginary_hashed,
sk.as_raw(),
))
Signature {
signature: RawSignature::new_hashed(x_real_hashed, x_imaginary_hashed, sk.as_raw()),
is_empty: false,
}
}
/// Verify the Signature against a PublicKey.
pub fn verify(&self, msg: &[u8], domain: u64, pk: &PublicKey) -> bool {
self.0.verify(msg, domain, pk.as_raw())
if self.is_empty {
return false;
}
self.signature.verify(msg, domain, pk.as_raw())
}
/// Verify the Signature against a PublicKey, where the message has already been hashed.
@@ -43,44 +51,72 @@ impl Signature {
x_imaginary_hashed: &[u8],
pk: &PublicKey,
) -> bool {
self.0
self.signature
.verify_hashed(x_real_hashed, x_imaginary_hashed, pk.as_raw())
}
/// Returns the underlying signature.
pub fn as_raw(&self) -> &RawSignature {
&self.0
&self.signature
}
/// Returns a new empty signature.
pub fn empty_signature() -> Self {
// Empty Signature is currently being represented as BLS::Signature.point_at_infinity()
// However it should be represented as vec![0; 96] but this
// would require all signatures to be represented in byte form as opposed to Signature
// Set RawSignature = infinity
let mut empty: Vec<u8> = vec![0; 96];
// Sets C_flag and B_flag to 1 and all else to 0
empty[0] += u8::pow(2, 6) + u8::pow(2, 7);
Signature(RawSignature::from_bytes(&empty).unwrap())
Signature {
signature: RawSignature::from_bytes(&empty).unwrap(),
is_empty: true,
}
}
// Converts a BLS Signature to bytes
pub fn as_bytes(&self) -> Vec<u8> {
if self.is_empty {
return vec![0; 96];
}
self.signature.as_bytes()
}
// Convert bytes to BLS Signature
pub fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
for byte in bytes {
if *byte != 0 {
let raw_signature =
RawSignature::from_bytes(&bytes).map_err(|_| DecodeError::Invalid)?;
return Ok(Signature {
signature: raw_signature,
is_empty: false,
});
}
}
Ok(Signature::empty_signature())
}
// Check for empty Signature
pub fn is_empty(&self) -> bool {
self.is_empty
}
}
impl Encodable for Signature {
fn ssz_append(&self, s: &mut SszStream) {
s.append_vec(&self.0.as_bytes());
s.append_vec(&self.as_bytes());
}
}
impl Decodable for Signature {
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
let raw_sig = RawSignature::from_bytes(&sig_bytes).map_err(|_| DecodeError::TooShort)?;
Ok((Signature(raw_sig), i))
let signature = Signature::from_bytes(&sig_bytes)?;
Ok((signature, i))
}
}
impl TreeHash for Signature {
fn hash_tree_root(&self) -> Vec<u8> {
hash(&self.0.as_bytes())
hash(&self.as_bytes())
}
}