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" }
|
int_to_bytes = { path = "../utils/int_to_bytes" }
|
||||||
integer-sqrt = "0.1"
|
integer-sqrt = "0.1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
merkle_proof = { path = "../utils/merkle_proof" }
|
||||||
ssz = { path = "../utils/ssz" }
|
ssz = { path = "../utils/ssz" }
|
||||||
|
ssz_derive = { path = "../utils/ssz_derive" }
|
||||||
types = { path = "../types" }
|
types = { path = "../types" }
|
||||||
rayon = "1.0"
|
rayon = "1.0"
|
||||||
|
@ -20,6 +20,11 @@ mod verify_proposer_slashing;
|
|||||||
mod verify_slashable_attestation;
|
mod verify_slashable_attestation;
|
||||||
mod verify_transfer;
|
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.
|
/// 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
|
/// Returns `Ok(())` if the block is valid and the state was successfully updated. Otherwise
|
||||||
@ -309,7 +314,8 @@ pub fn process_deposits(
|
|||||||
Invalid::MaxDepositsExceeded
|
Invalid::MaxDepositsExceeded
|
||||||
);
|
);
|
||||||
for (i, deposit) in deposits.iter().enumerate() {
|
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
|
state
|
||||||
.process_deposit(
|
.process_deposit(
|
||||||
|
@ -292,6 +292,9 @@ pub enum DepositInvalid {
|
|||||||
///
|
///
|
||||||
/// (state_index, deposit_index)
|
/// (state_index, deposit_index)
|
||||||
BadIndex(u64, u64),
|
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);
|
impl_into_with_index_without_beacon_error!(DepositValidationError, DepositInvalid);
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
use super::errors::{DepositInvalid as Invalid, DepositValidationError as Error};
|
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::*;
|
use types::*;
|
||||||
|
|
||||||
/// Indicates if a `Deposit` is valid to be included in a block in the current epoch of the given
|
/// 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(
|
pub fn verify_deposit(
|
||||||
state: &BeaconState,
|
state: &BeaconState,
|
||||||
deposit: &Deposit,
|
deposit: &Deposit,
|
||||||
_spec: &ChainSpec,
|
verify_merkle_branch: bool,
|
||||||
|
spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// TODO: verify serialized deposit data.
|
|
||||||
|
|
||||||
verify!(
|
verify!(
|
||||||
deposit.index == state.deposit_index,
|
deposit.index == state.deposit_index,
|
||||||
Invalid::BadIndex(state.deposit_index, 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(())
|
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