Implement deposit merkle root verification.
It is currently disabled, but it's there for later.
This commit is contained in:
parent
60098a051d
commit
f479beb87e
@ -18,6 +18,8 @@ hashing = { path = "../utils/hashing" }
|
||||
int_to_bytes = { path = "../utils/int_to_bytes" }
|
||||
integer-sqrt = "0.1"
|
||||
log = "0.4"
|
||||
merkle_proof = { path = "../utils/merkle_proof" }
|
||||
ssz = { path = "../utils/ssz" }
|
||||
ssz_derive = { path = "../utils/ssz_derive" }
|
||||
types = { path = "../types" }
|
||||
rayon = "1.0"
|
||||
|
@ -20,6 +20,11 @@ mod verify_proposer_slashing;
|
||||
mod verify_slashable_attestation;
|
||||
mod verify_transfer;
|
||||
|
||||
// Set to `true` to check the merkle proof that a deposit is in the eth1 deposit root.
|
||||
//
|
||||
// Presently disabled to make testing easier.
|
||||
const VERIFY_DEPOSIT_MERKLE_PROOFS: bool = false;
|
||||
|
||||
/// Updates the state for a new block, whilst validating that the block is valid.
|
||||
///
|
||||
/// Returns `Ok(())` if the block is valid and the state was successfully updated. Otherwise
|
||||
@ -309,7 +314,8 @@ pub fn process_deposits(
|
||||
Invalid::MaxDepositsExceeded
|
||||
);
|
||||
for (i, deposit) in deposits.iter().enumerate() {
|
||||
verify_deposit(state, deposit, spec).map_err(|e| e.into_with_index(i))?;
|
||||
verify_deposit(state, deposit, VERIFY_DEPOSIT_MERKLE_PROOFS, spec)
|
||||
.map_err(|e| e.into_with_index(i))?;
|
||||
|
||||
state
|
||||
.process_deposit(
|
||||
|
@ -292,6 +292,9 @@ pub enum DepositInvalid {
|
||||
///
|
||||
/// (state_index, deposit_index)
|
||||
BadIndex(u64, u64),
|
||||
/// The specified `branch` and `index` did not form a valid proof that the deposit is included
|
||||
/// in the eth1 deposit root.
|
||||
BadMerkleProof,
|
||||
}
|
||||
|
||||
impl_into_with_index_without_beacon_error!(DepositValidationError, DepositInvalid);
|
||||
|
@ -1,4 +1,8 @@
|
||||
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
|
||||
@ -12,16 +16,58 @@ use types::*;
|
||||
pub fn verify_deposit(
|
||||
state: &BeaconState,
|
||||
deposit: &Deposit,
|
||||
_spec: &ChainSpec,
|
||||
verify_merkle_branch: bool,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
// TODO: verify serialized deposit data.
|
||||
|
||||
verify!(
|
||||
deposit.index == state.deposit_index,
|
||||
Invalid::BadIndex(state.deposit_index, deposit.index)
|
||||
);
|
||||
|
||||
// TODO: verify merkle branch.
|
||||
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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user