From 7f2121205aed5d0a5dadd11e09e2970f57e56254 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 29 Apr 2020 11:37:14 +1000 Subject: [PATCH] Ensure genesis is not triggered too early (#1052) --- beacon_node/genesis/src/eth1_genesis_service.rs | 14 ++++++++++---- eth2/state_processing/src/genesis.rs | 17 +++++++++++++---- eth2/state_processing/src/lib.rs | 5 ++++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/beacon_node/genesis/src/eth1_genesis_service.rs b/beacon_node/genesis/src/eth1_genesis_service.rs index 14df35fa1..ffefb58b2 100644 --- a/beacon_node/genesis/src/eth1_genesis_service.rs +++ b/beacon_node/genesis/src/eth1_genesis_service.rs @@ -10,7 +10,7 @@ use futures::{ use parking_lot::Mutex; use slog::{debug, error, info, trace, Logger}; use state_processing::{ - initialize_beacon_state_from_eth1, is_valid_genesis_state, + eth2_genesis_time, initialize_beacon_state_from_eth1, is_valid_genesis_state, per_block_processing::process_deposit, process_activations, }; use std::sync::Arc; @@ -223,9 +223,15 @@ impl Eth1GenesisService { .blocks() .read() .iter() - // It's only worth scanning blocks that have timestamps _after_ genesis time. It's - // impossible for any other block to trigger genesis. - .filter(|block| block.timestamp >= spec.min_genesis_time) + // Filter out any blocks that would result in a genesis time that is earlier than + // `MIN_GENESIS_TIME`. + // + // Note: any `SafeArith` errors are suppressed here; we simply skip blocks that cause + // overflow/div-by-zero. + .filter(|block| { + eth2_genesis_time(block.timestamp, spec) + .map_or(false, |t| t >= spec.min_genesis_time) + }) // The block cache might be more recently updated than deposit cache. Restrict any // block numbers that are not known by all caches. .filter(|block| { diff --git a/eth2/state_processing/src/genesis.rs b/eth2/state_processing/src/genesis.rs index 9ae9fabdc..d219b9090 100644 --- a/eth2/state_processing/src/genesis.rs +++ b/eth2/state_processing/src/genesis.rs @@ -1,6 +1,6 @@ use super::per_block_processing::{errors::BlockProcessingError, process_deposit}; use crate::common::DepositDataTree; -use safe_arith::SafeArith; +use safe_arith::{ArithError, SafeArith}; use tree_hash::TreeHash; use types::DEPOSIT_TREE_DEPTH; use types::*; @@ -15,9 +15,7 @@ pub fn initialize_beacon_state_from_eth1( deposits: Vec, spec: &ChainSpec, ) -> Result, BlockProcessingError> { - let genesis_time = eth1_timestamp - .safe_sub(eth1_timestamp.safe_rem(spec.min_genesis_delay)?)? - .safe_add(2.safe_mul(spec.min_genesis_delay)?)?; + let genesis_time = eth2_genesis_time(eth1_timestamp, spec)?; let eth1_data = Eth1Data { // Temporary deposit root deposit_root: Hash256::zero(), @@ -79,3 +77,14 @@ pub fn process_activations( } Ok(()) } + +/// Returns the `state.genesis_time` for the corresponding `eth1_timestamp`. +/// +/// Does _not_ ensure that the time is greater than `MIN_GENESIS_TIME`. +/// +/// Spec v0.11.1 +pub fn eth2_genesis_time(eth1_timestamp: u64, spec: &ChainSpec) -> Result { + eth1_timestamp + .safe_sub(eth1_timestamp.safe_rem(spec.min_genesis_delay)?)? + .safe_add(2.safe_mul(spec.min_genesis_delay)?) +} diff --git a/eth2/state_processing/src/lib.rs b/eth2/state_processing/src/lib.rs index 86dc2294f..7b871c1db 100644 --- a/eth2/state_processing/src/lib.rs +++ b/eth2/state_processing/src/lib.rs @@ -10,7 +10,10 @@ pub mod per_epoch_processing; pub mod per_slot_processing; pub mod test_utils; -pub use genesis::{initialize_beacon_state_from_eth1, is_valid_genesis_state, process_activations}; +pub use genesis::{ + eth2_genesis_time, initialize_beacon_state_from_eth1, is_valid_genesis_state, + process_activations, +}; pub use per_block_processing::{ block_signature_verifier, errors::BlockProcessingError, per_block_processing, signature_sets, BlockSignatureStrategy, BlockSignatureVerifier, VerifySignatures,