lighthouse/eth2/state_processing/src/per_block_processing/verify_deposit.rs
Paul Hauner f479beb87e
Implement deposit merkle root verification.
It is currently disabled, but it's there for later.
2019-03-08 09:26:03 +11:00

74 lines
2.0 KiB
Rust

use super::errors::{DepositInvalid as Invalid, DepositValidationError as Error};
use hashing::hash;
use merkle_proof::verify_merkle_proof;
use ssz::ssz_encode;
use ssz_derive::Encode;
use types::*;
/// Indicates if a `Deposit` is valid to be included in a block in the current epoch of the given
/// state.
///
/// Returns `Ok(())` if the `Deposit` is valid, otherwise indicates the reason for invalidity.
///
/// Note: this function is incomplete.
///
/// Spec v0.4.0
pub fn verify_deposit(
state: &BeaconState,
deposit: &Deposit,
verify_merkle_branch: bool,
spec: &ChainSpec,
) -> Result<(), Error> {
verify!(
deposit.index == state.deposit_index,
Invalid::BadIndex(state.deposit_index, deposit.index)
);
if verify_merkle_branch {
verify!(
verify_deposit_merkle_proof(state, deposit, spec),
Invalid::BadMerkleProof
);
}
Ok(())
}
/// Verify that a deposit is included in the state's eth1 deposit root.
///
/// Spec v0.4.0
fn verify_deposit_merkle_proof(state: &BeaconState, deposit: &Deposit, spec: &ChainSpec) -> bool {
let leaf = hash(&get_serialized_deposit_data(deposit));
verify_merkle_proof(
Hash256::from_slice(&leaf),
&deposit.branch,
spec.deposit_contract_tree_depth as usize,
deposit.index as usize,
state.latest_eth1_data.deposit_root,
)
}
/// Helper struct for easily getting the serialized data generated by the deposit contract.
///
/// Spec v0.4.0
#[derive(Encode)]
struct SerializedDepositData {
amount: u64,
timestamp: u64,
input: DepositInput,
}
/// Return the serialized data generated by the deposit contract that is used to generate the
/// merkle proof.
///
/// Spec v0.4.0
fn get_serialized_deposit_data(deposit: &Deposit) -> Vec<u8> {
let serialized_deposit_data = SerializedDepositData {
amount: deposit.deposit_data.amount,
timestamp: deposit.deposit_data.timestamp,
input: deposit.deposit_data.deposit_input.clone(),
};
ssz_encode(&serialized_deposit_data)
}