From 3182540d9f955b7a6d0708e55a97594e6687b556 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 22 Feb 2017 18:24:22 +0100 Subject: [PATCH] Tweak some checks. (#4633) * Tweak some checks. * Fixed build and added a difficulty test --- ethcore/src/ethereum/ethash.rs | 18 ++++++++++++++++++ ethcore/src/header.rs | 2 +- ethcore/src/verification/queue/kind.rs | 2 +- ethcore/src/verification/verification.rs | 14 ++++++++------ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 6c7b91d39..bff11fa2a 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -835,4 +835,22 @@ mod tests { ethash.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002)); assert_eq!(*header.gas_limit(), U256::from(150_002)); } + + #[test] + fn difficulty_max_timestamp() { + let spec = new_homestead_test(); + let ethparams = get_default_ethash_params(); + let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new()); + + let mut parent_header = Header::default(); + parent_header.set_number(1000000); + parent_header.set_difficulty(U256::from_str("b69de81a22b").unwrap()); + parent_header.set_timestamp(1455404053); + let mut header = Header::default(); + header.set_number(parent_header.number() + 1); + header.set_timestamp(u64::max_value()); + + let difficulty = ethash.calculate_difficulty(&header, &parent_header); + assert_eq!(U256::from(12543204905719u64), difficulty); + } } diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 1ec98708e..60b9dcb46 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -276,7 +276,7 @@ impl Decodable for Header { number: r.val_at(8)?, gas_limit: r.val_at(9)?, gas_used: r.val_at(10)?, - timestamp: r.val_at(11)?, + timestamp: min(r.val_at::(11)?, u64::max_value().into()).as_u64(), extra_data: r.val_at(12)?, seal: vec![], hash: RefCell::new(Some(r.as_raw().sha3())), diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index c10fce26d..6ab6d692e 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -185,7 +185,7 @@ pub mod headers { type Verified = Header; fn create(input: Self::Input, engine: &Engine) -> Result { - verify_header_params(&input, engine).map(|_| input) + verify_header_params(&input, engine, true).map(|_| input) } fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result { diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 548a4e71b..34a4ccbd0 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -51,12 +51,12 @@ impl HeapSizeOf for PreverifiedBlock { /// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error> { - verify_header_params(&header, engine)?; + verify_header_params(&header, engine, true)?; verify_block_integrity(bytes, &header.transactions_root(), &header.uncles_hash())?; engine.verify_block_basic(&header, Some(bytes))?; for u in UntrustedRlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { let u = u?; - verify_header_params(&u, engine)?; + verify_header_params(&u, engine, false)?; engine.verify_block_basic(&u, None)?; } // Verify transactions. @@ -195,7 +195,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> } /// Check basic header parameters. -pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Error> { +pub fn verify_header_params(header: &Header, engine: &Engine, is_full: bool) -> Result<(), Error> { if header.number() >= From::from(BlockNumber::max_value()) { return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { max: Some(From::from(BlockNumber::max_value())), min: None, found: header.number() }))) } @@ -210,9 +210,11 @@ pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Erro if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size { return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() }))); } - let max_time = get_time().sec as u64 + 30; - if header.timestamp() > max_time { - return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() }))) + if is_full { + let max_time = get_time().sec as u64 + 30; + if header.timestamp() > max_time { + return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() }))) + } } Ok(()) }