Use SignatureBytes and PublicKeyBytes for deposits (#472)

* Replace deposit signatures with SignatureBytes, a struct which lazyly parsers signatures only on demand.

* check byte length when parsing SignatureBytes

* add comment to struct

* distinguish BadSignature and BadSignatureBytes in verify_deposit_signature

* add test for valid signature

* Implements TryInto<Signature> for &SignatureBytes and From<Signature> for &SignatureBytes

* add and use PublicKeyBytes + fix formatting

* fix compiler warning + docs for macro generated structs

* adds tests to ensure correct byte lengths

* small style improvement as suggested by michaelsproul
This commit is contained in:
blacktemplar
2019-08-06 05:49:11 +02:00
committed by Paul Hauner
parent 845f336a59
commit 01054ecf2f
14 changed files with 286 additions and 18 deletions

View File

@@ -1,6 +1,7 @@
use crate::test_utils::TestRandom;
use crate::*;
use bls::{PublicKey, Signature};
use bls::{PublicKeyBytes, SignatureBytes};
use std::convert::From;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
@@ -25,11 +26,11 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
TestRandom,
)]
pub struct DepositData {
pub pubkey: PublicKey,
pub pubkey: PublicKeyBytes,
pub withdrawal_credentials: Hash256,
pub amount: u64,
#[signed_root(skip_hashing)]
pub signature: Signature,
pub signature: SignatureBytes,
}
impl DepositData {
@@ -42,11 +43,11 @@ impl DepositData {
epoch: Epoch,
fork: &Fork,
spec: &ChainSpec,
) -> Signature {
) -> SignatureBytes {
let msg = self.signed_root();
let domain = spec.get_domain(epoch, Domain::Deposit, fork);
Signature::new(msg.as_slice(), domain, secret_key)
SignatureBytes::from(Signature::new(msg.as_slice(), domain, secret_key))
}
}

View File

@@ -1,5 +1,5 @@
use crate::*;
use bls::get_withdrawal_credentials;
use bls::{get_withdrawal_credentials, PublicKeyBytes, SignatureBytes};
/// Builds an deposit to be used for testing purposes.
///
@@ -14,10 +14,10 @@ impl TestingDepositBuilder {
let deposit = Deposit {
proof: vec![].into(),
data: DepositData {
pubkey,
pubkey: PublicKeyBytes::from(pubkey),
withdrawal_credentials: Hash256::zero(),
amount,
signature: Signature::empty_signature(),
signature: SignatureBytes::empty(),
},
};
@@ -34,7 +34,7 @@ impl TestingDepositBuilder {
&get_withdrawal_credentials(&keypair.pk, spec.bls_withdrawal_prefix_byte)[..],
);
self.deposit.data.pubkey = keypair.pk.clone();
self.deposit.data.pubkey = PublicKeyBytes::from(keypair.pk.clone());
self.deposit.data.withdrawal_credentials = withdrawal_credentials;
self.deposit.data.signature =

View File

@@ -7,8 +7,10 @@ mod aggregate_signature;
mod bitfield;
mod hash256;
mod public_key;
mod public_key_bytes;
mod secret_key;
mod signature;
mod signature_bytes;
pub trait TestRandom {
fn random_for_test(rng: &mut impl RngCore) -> Self;
@@ -99,3 +101,5 @@ macro_rules! impl_test_random_for_u8_array {
impl_test_random_for_u8_array!(4);
impl_test_random_for_u8_array!(32);
impl_test_random_for_u8_array!(48);
impl_test_random_for_u8_array!(96);

View File

@@ -0,0 +1,19 @@
use std::convert::From;
use bls::{PublicKeyBytes, BLS_PUBLIC_KEY_BYTE_SIZE};
use super::*;
impl TestRandom for PublicKeyBytes {
fn random_for_test(rng: &mut impl RngCore) -> Self {
//50-50 chance for signature to be "valid" or invalid
if bool::random_for_test(rng) {
//valid signature
PublicKeyBytes::from(PublicKey::random_for_test(rng))
} else {
//invalid signature, just random bytes
PublicKeyBytes::from_bytes(&<[u8; BLS_PUBLIC_KEY_BYTE_SIZE]>::random_for_test(rng))
.unwrap()
}
}
}

View File

@@ -0,0 +1,17 @@
use bls::{SignatureBytes, BLS_SIG_BYTE_SIZE};
use super::*;
use std::convert::From;
impl TestRandom for SignatureBytes {
fn random_for_test(rng: &mut impl RngCore) -> Self {
//50-50 chance for signature to be "valid" or invalid
if bool::random_for_test(rng) {
//valid signature
SignatureBytes::from(Signature::random_for_test(rng))
} else {
//invalid signature, just random bytes
SignatureBytes::from_bytes(&<[u8; BLS_SIG_BYTE_SIZE]>::random_for_test(rng)).unwrap()
}
}
}