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

@@ -349,6 +349,8 @@ pub enum DepositInvalid {
BadIndex { state: u64, deposit: u64 },
/// The signature (proof-of-possession) does not match the given pubkey.
BadSignature,
/// The signature does not represent a valid BLS signature.
BadSignatureBytes,
/// The specified `branch` and `index` did not form a valid proof that the deposit is included
/// in the eth1 deposit root.
BadMerkleProof,

View File

@@ -1,5 +1,6 @@
use super::errors::{DepositInvalid as Invalid, DepositValidationError as Error};
use merkle_proof::verify_merkle_proof;
use std::convert::TryInto;
use tree_hash::{SignedRoot, TreeHash};
use types::*;
@@ -10,15 +11,17 @@ pub fn verify_deposit_signature<T: EthSpec>(
state: &BeaconState<T>,
deposit: &Deposit,
spec: &ChainSpec,
pubkey: &PublicKey,
) -> Result<(), Error> {
// Note: Deposits are valid across forks, thus the deposit domain is computed
// with the fork zeroed.
let domain = spec.get_domain(state.current_epoch(), Domain::Deposit, &Fork::default());
let signature: Signature = (&deposit.data.signature)
.try_into()
.map_err(|_| Error::Invalid(Invalid::BadSignatureBytes))?;
verify!(
deposit
.data
.signature
.verify(&deposit.data.signed_root(), domain, &deposit.data.pubkey,),
signature.verify(&deposit.data.signed_root(), domain, pubkey),
Invalid::BadSignature
);
@@ -33,9 +36,9 @@ pub fn verify_deposit_signature<T: EthSpec>(
/// Errors if the state's `pubkey_cache` is not current.
pub fn get_existing_validator_index<T: EthSpec>(
state: &BeaconState<T>,
deposit: &Deposit,
pub_key: &PublicKey,
) -> Result<Option<u64>, Error> {
let validator_index = state.get_validator_index(&deposit.data.pubkey)?;
let validator_index = state.get_validator_index(pub_key)?;
Ok(validator_index.map(|idx| idx as u64))
}