Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: do not perform future timestamp checks post-merge #3884

Merged
merged 5 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions crates/consensus/beacon/src/beacon_consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
use reth_consensus_common::validation;
use reth_interfaces::consensus::{Consensus, ConsensusError};
use reth_primitives::{
constants::MAXIMUM_EXTRA_DATA_SIZE, Chain, ChainSpec, Hardfork, Header, SealedBlock,
SealedHeader, EMPTY_OMMER_ROOT, U256,
constants::{ALLOWED_FUTURE_BLOCK_TIME_SECONDS, MAXIMUM_EXTRA_DATA_SIZE},
Chain, ChainSpec, Hardfork, Header, SealedBlock, SealedHeader, EMPTY_OMMER_ROOT, U256,
};
use std::sync::Arc;
use std::{sync::Arc, time::SystemTime};

/// Ethereum beacon consensus
///
Expand Down Expand Up @@ -59,6 +59,14 @@ impl Consensus for BeaconConsensus {
return Err(ConsensusError::TheMergeOmmerRootIsNotEmpty)
}

// Post-merge, the consensus layer is expected to perform checks such that the block
// timestamp is a function of the slot. This is different from pre-merge, where blocks
// are only allowed to be in the future (compared to the system's clock) by a certain
// threshold.
//
// Block validation with respect to the parent should ensure that the block timestamp
// is greater than its parent timestamp.

// validate header extradata for all networks post merge
validate_header_extradata(header)?;

Expand All @@ -69,6 +77,17 @@ impl Consensus for BeaconConsensus {
// * difficulty, mix_hash & nonce aka PoW stuff
// low priority as syncing is done in reverse order

// Check if timestamp is in future. Clock can drift but this can be consensus issue.
let present_timestamp =
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();

if header.timestamp > present_timestamp + ALLOWED_FUTURE_BLOCK_TIME_SECONDS {
return Err(ConsensusError::TimestampIsInFuture {
timestamp: header.timestamp,
present_timestamp,
})
}

// Goerli exception:
// * If the network is goerli pre-merge, ignore the extradata check, since we do not
// support clique.
Expand Down
15 changes: 1 addition & 14 deletions crates/consensus/common/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use reth_primitives::{
SealedHeader, Transaction, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxLegacy,
};
use reth_provider::{AccountReader, HeaderProvider, WithdrawalsProvider};
use std::{
collections::{hash_map::Entry, HashMap},
time::SystemTime,
};
use std::collections::{hash_map::Entry, HashMap};

/// Validate header standalone
pub fn validate_header_standalone(
Expand All @@ -23,16 +20,6 @@ pub fn validate_header_standalone(
})
}

// Check if timestamp is in future. Clock can drift but this can be consensus issue.
let present_timestamp =
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
if header.timestamp > present_timestamp {
return Err(ConsensusError::TimestampIsInFuture {
timestamp: header.timestamp,
present_timestamp,
})
}

// Check if base fee is set.
if chain_spec.fork(Hardfork::London).active_at_block(header.number) &&
header.base_fee_per_gas.is_none()
Expand Down
9 changes: 9 additions & 0 deletions crates/primitives/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ pub const EMPTY_WITHDRAWALS: H256 = EMPTY_SET_HASH;
/// the database.
pub const BEACON_CONSENSUS_REORG_UNWIND_DEPTH: u64 = 3;

/// Max seconds from current time allowed for blocks, before they're considered future blocks.
///
/// This is only used when checking whether or not the timestamp for pre-merge blocks is in the
/// future.
///
/// See:
/// <https://github.com/ethereum/go-ethereum/blob/a196f3e8a22b6ad22ced5c2e3baf32bc3ebd4ec9/consensus/ethash/consensus.go#L227-L229>
pub const ALLOWED_FUTURE_BLOCK_TIME_SECONDS: u64 = 15;

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading