From ca67e1c8b3d202ecf314d4a6c5b893109a62cbe6 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 19 Feb 2019 20:11:06 +0100 Subject: [PATCH 1/4] fix(extract `timestamp_checked_add` as lib) --- Cargo.lock | 6 +++ Cargo.toml | 3 +- ethcore/Cargo.toml | 1 + ethcore/src/engines/authority_round/mod.rs | 16 ++++-- ethcore/src/lib.rs | 1 + ethcore/src/verification/verification.rs | 37 +++---------- util/time-utils/Cargo.toml | 9 ++++ util/time-utils/src/lib.rs | 62 ++++++++++++++++++++++ whisper/Cargo.toml | 1 + whisper/src/lib.rs | 1 + whisper/src/message.rs | 19 ++++--- whisper/src/net/mod.rs | 9 ++-- 12 files changed, 123 insertions(+), 42 deletions(-) create mode 100644 util/time-utils/Cargo.toml create mode 100644 util/time-utils/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index b6c0b3ef61f..7629bac4ebc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -752,6 +752,7 @@ dependencies = [ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "stats 0.1.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time-utils 0.1.0", "trace-time 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-standardmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2819,6 +2820,7 @@ dependencies = [ "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "time-utils 0.1.0", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3774,6 +3776,10 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "time-utils" +version = "0.1.0" + [[package]] name = "timer" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index ee4440dd010..a783175607f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,7 +138,8 @@ members = [ "util/triehash-ethereum", "util/keccak-hasher", "util/patricia-trie-ethereum", - "util/fastmap" + "util/fastmap", + "util/time-utils" ] [patch.crates-io] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 2d26ba03814..3b8d60af8e9 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -63,6 +63,7 @@ serde = "1.0" serde_derive = "1.0" stats = { path = "../util/stats" } tempdir = {version="0.3", optional = true} +time-utils = { path = "../util/time-utils" } trace-time = "0.1" triehash-ethereum = { version = "0.2", path = "../util/triehash-ethereum" } unexpected = { path = "../util/unexpected" } diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 31062d80f3d..e6a0fac0f8d 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -42,6 +42,7 @@ use itertools::{self, Itertools}; use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp}; use ethereum_types::{H256, H520, Address, U128, U256}; use parking_lot::{Mutex, RwLock}; +use time_utils::CheckedSystemTime; use types::BlockNumber; use types::header::{Header, ExtendedHeader}; use types::ancestry_action::AncestryAction; @@ -574,8 +575,16 @@ fn verify_timestamp(step: &Step, header_step: u64) -> Result<(), BlockError> { // NOTE This error might be returned only in early stage of verification (Stage 1). // Returning it further won't recover the sync process. trace!(target: "engine", "verify_timestamp: block too early"); - let oob = oob.map(|n| SystemTime::now() + Duration::from_secs(n)); - Err(BlockError::TemporarilyInvalid(oob).into()) + + let now = SystemTime::now(); + let found = CheckedSystemTime::checked_add(now, Duration::from_secs(oob.found)) + .ok_or(BlockError::TimestampOverflow)?; + let max = oob.max.and_then(|m| CheckedSystemTime::checked_add(now, Duration::from_secs(m))); + let min = oob.max.and_then(|m| CheckedSystemTime::checked_add(now, Duration::from_secs(m))); + + let new_oob = OutOfBounds { min, max, found }; + + Err(BlockError::TemporarilyInvalid(new_oob).into()) }, Ok(_) => Ok(()), } @@ -611,6 +620,7 @@ fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof: stream.out() } + fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> { let rlp = Rlp::new(combined); Ok(( @@ -626,7 +636,7 @@ trait AsMillis { impl AsMillis for Duration { fn as_millis(&self) -> u64 { - self.as_secs()*1_000 + (self.subsec_nanos()/1_000_000) as u64 + self.as_secs() * 1_000 + (self.subsec_nanos() / 1_000_000) as u64 } } diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 17b33025a1c..6578d360714 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -99,6 +99,7 @@ extern crate rlp; extern crate rustc_hex; extern crate serde; extern crate stats; +extern crate time_utils; extern crate triehash_ethereum as triehash; extern crate unexpected; extern crate using_queue; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 2ce9f9de304..82812b0246c 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -36,29 +36,11 @@ use call_contract::CallContract; use client::BlockInfo; use engines::EthEngine; use error::{BlockError, Error}; +use time_utils::CheckedSystemTime; use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; use verification::queue::kind::blocks::Unverified; - -/// Returns `Ok` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because -/// it is platform specific, may be i32 or i64. -/// -/// `Err Result { - let d1 = sys.duration_since(UNIX_EPOCH).map_err(|_| BlockError::TimestampOverflow)?; - let total_time = d1.checked_add(d2).ok_or(BlockError::TimestampOverflow)?; - - if total_time.as_secs() <= i32::max_value() as u64 { - Ok(sys + d2) - } else { - Err(BlockError::TimestampOverflow) - } -} - /// Preprocessed block data gathered in `verify_block_unordered` call pub struct PreverifiedBlock { /// Populated block header @@ -323,9 +305,11 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool, if is_full { const ACCEPTABLE_DRIFT: Duration = Duration::from_secs(15); + // this will resist overflow until `year 2037` let max_time = SystemTime::now() + ACCEPTABLE_DRIFT; let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9; - let timestamp = timestamp_checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp()))?; + let timestamp = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp())) + .ok_or(BlockError::TimestampOverflow)?; if timestamp > invalid_threshold { return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp }))) @@ -347,8 +331,10 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result let gas_limit_divisor = engine.params().gas_limit_bound_divisor; if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) { - let min = timestamp_checked_add(SystemTime::now(), Duration::from_secs(parent.timestamp().saturating_add(1)))?; - let found = timestamp_checked_add(SystemTime::now(), Duration::from_secs(header.timestamp()))?; + let min = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_secs(parent.timestamp().saturating_add(1))) + .ok_or(BlockError::TimestampOverflow)?; + let found = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_secs(header.timestamp())) + .ok_or(BlockError::TimestampOverflow)?; return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found }))) } if header.number() != parent.number() + 1 { @@ -835,11 +821,4 @@ mod tests { check_fail(unordered_test(&create_test_block_with_data(&header, &bad_transactions, &[]), &engine), TooManyTransactions(keypair.address())); unordered_test(&create_test_block_with_data(&header, &good_transactions, &[]), &engine).unwrap(); } - - #[test] - fn checked_add_systime_dur() { - assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 + 1, 0)).is_err()); - assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64, 0)).is_ok()); - assert!(timestamp_checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 - 1, 1_000_000_000)).is_ok()); - } } diff --git a/util/time-utils/Cargo.toml b/util/time-utils/Cargo.toml new file mode 100644 index 00000000000..38e7dd02c68 --- /dev/null +++ b/util/time-utils/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "time-utils" +version = "0.1.0" +authors = ["Parity Technologies "] +description = "Time utilities for checked arithmetic" +license = "GPL3" +edition = "2018" + +[dependencies] diff --git a/util/time-utils/src/lib.rs b/util/time-utils/src/lib.rs new file mode 100644 index 00000000000..6af5424936b --- /dev/null +++ b/util/time-utils/src/lib.rs @@ -0,0 +1,62 @@ +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +/// Temporary trait for `SystemTime::checked_add` until `Rust 1.33` is available +pub trait CheckedSystemTime { + /// Returns `Some` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because + /// it is platform specific, possible representations are i32, i64, u64 and Duration. `None` otherwise + fn checked_add(self, _d: Duration) -> Option; + /// Returns `Some` when the result is successful and `None` when it is not + fn checked_sub(self, _d: Duration) -> Option; +} + +impl CheckedSystemTime for SystemTime { + fn checked_add(self, dur: Duration) -> Option { + let this_dur = self.duration_since(UNIX_EPOCH).ok()?; + let total_time = this_dur.checked_add(dur)?; + + if total_time.as_secs() <= i32::max_value() as u64 { + Some(self + dur) + } else { + None + } + } + + fn checked_sub(self, dur: Duration) -> Option { + let this_dur = self.duration_since(UNIX_EPOCH).ok()?; + let total_time = this_dur.checked_sub(dur)?; + + if total_time.as_secs() <= i32::max_value() as u64 { + Some(self - dur) + } else { + None + } + } +} + +/// Temporary trait for `Duration::as_millis` until `Rust 1.33` is available +pub trait AsMillis { + /// Duration represented as milliseconds + fn as_millis(&self) -> u128; +} + +impl AsMillis for Duration { + fn as_millis(&self) -> u128 { + self.as_secs() as u128 * 1_000 + (self.subsec_nanos() / 1_000_000) as u128 + } +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + use super::CheckedSystemTime; + use std::time::{Duration, SystemTime, UNIX_EPOCH}; + + assert!(CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 + 1, 0)).is_none()); + assert!(CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64, 0)).is_some()); + assert!(CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::new(i32::max_value() as u64 - 1, 1_000_000_000)).is_some()); + + assert!(CheckedSystemTime::checked_sub(UNIX_EPOCH, Duration::from_secs(120)).is_none()); + assert!(CheckedSystemTime::checked_sub(SystemTime::now(), Duration::from_secs(1000)).is_some()); + } +} diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index 5c3548a50c8..97aa8f23ac3 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -24,6 +24,7 @@ serde_json = "1.0" slab = "0.3" smallvec = "0.6" tiny-keccak = "1.4" +time-utils = { path = "../util/time-utils" } jsonrpc-core = "10.0.1" jsonrpc-derive = "10.0.2" diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index 0e79946d9a5..ee2c6d21362 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -32,6 +32,7 @@ extern crate serde; extern crate slab; extern crate smallvec; extern crate tiny_keccak; +extern crate time_utils; extern crate jsonrpc_core; extern crate jsonrpc_derive; diff --git a/whisper/src/message.rs b/whisper/src/message.rs index f8e8565a8eb..d559bfdb0a9 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -23,6 +23,7 @@ use ethereum_types::{H256, H512}; use rlp::{self, DecoderError, RlpStream, Rlp}; use smallvec::SmallVec; use tiny_keccak::{keccak256, Keccak}; +use time_utils::CheckedSystemTime; /// Work-factor proved. Takes 3 parameters: size of message, time to live, /// and hash. @@ -117,6 +118,7 @@ pub enum Error { EmptyTopics, LivesTooLong, IssuedInFuture, + TimestampOverflow, ZeroTTL, } @@ -133,6 +135,7 @@ impl fmt::Display for Error { Error::LivesTooLong => write!(f, "Message claims to be issued before the unix epoch."), Error::IssuedInFuture => write!(f, "Message issued in future."), Error::ZeroTTL => write!(f, "Message live for zero time."), + Error::TimestampOverflow => write!(f, "Timestamp overflow"), Error::EmptyTopics => write!(f, "Message has no topics."), } } @@ -255,11 +258,11 @@ pub struct Message { impl Message { /// Create a message from creation parameters. /// Panics if TTL is 0. - pub fn create(params: CreateParams) -> Result { + pub fn create(params: CreateParams) -> Result { use byteorder::{BigEndian, ByteOrder}; use rand::{Rng, SeedableRng, XorShiftRng}; - if params.topics.is_empty() { return Err(EmptyTopics) } + if params.topics.is_empty() { return Err(Error::EmptyTopics) } let mut rng = { let mut thread_rng = ::rand::thread_rng(); @@ -270,7 +273,8 @@ impl Message { assert!(params.ttl > 0); let expiry = { - let after_mining = SystemTime::now() + Duration::from_millis(params.work); + let after_mining = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_millis(params.work)). + ok_or(Error::TimestampOverflow)?; let since_epoch = after_mining.duration_since(time::UNIX_EPOCH) .expect("time after now is after unix epoch; qed"); @@ -357,7 +361,10 @@ impl Message { (envelope.expiry - envelope.ttl).saturating_sub(LEEWAY_SECONDS) ); - if time::UNIX_EPOCH + issue_time_adjusted > now { + let issue_time_adjusted = CheckedSystemTime::checked_add(time::UNIX_EPOCH, issue_time_adjusted) + .ok_or(Error::TimestampOverflow)?; + + if issue_time_adjusted > now { return Err(Error::IssuedInFuture); } @@ -400,8 +407,8 @@ impl Message { } /// Get the expiry time. - pub fn expiry(&self) -> SystemTime { - time::UNIX_EPOCH + Duration::from_secs(self.envelope.expiry) + pub fn expiry(&self) -> Option { + CheckedSystemTime::checked_add(time::UNIX_EPOCH, Duration::from_secs(self.envelope.expiry)) } /// Get the topics. diff --git a/whisper/src/net/mod.rs b/whisper/src/net/mod.rs index 64431d14263..d263f6cfbd9 100644 --- a/whisper/src/net/mod.rs +++ b/whisper/src/net/mod.rs @@ -223,7 +223,10 @@ impl Messages { } } - let expiry = message.expiry(); + let expiry = match message.expiry() { + Some(time) => time, + _ => return false, + }; self.cumulative_size += message.encoded_size(); @@ -232,8 +235,8 @@ impl Messages { let sorted_entry = SortedEntry { slab_id: id, - work_proved: work_proved, - expiry: expiry, + work_proved, + expiry, }; match self.sorted.binary_search(&sorted_entry) { From 48b3b88871f6ca84d2f6a87d6b6730f4ffa6cbad Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 19 Feb 2019 21:33:18 +0100 Subject: [PATCH 2/4] fix(whisper types): remove unused `EmptyTopics` --- whisper/src/message.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/whisper/src/message.rs b/whisper/src/message.rs index d559bfdb0a9..3cd2bf9300f 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -229,10 +229,6 @@ impl rlp::Decodable for Envelope { } } -/// Error indicating no topics. -#[derive(Debug, Copy, Clone)] -pub struct EmptyTopics; - /// Message creation parameters. /// Pass this to `Message::create` to make a message. pub struct CreateParams { From ae104343fcd26e3dbed90e26227a6252f1e9ace0 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 11 Mar 2019 11:44:03 +0100 Subject: [PATCH 3/4] fix(time-lib): feature-flag to use time-lib or std This commit adds conditional compilation checks that falls back to `our time-lib` when `time_checked_add` is not available in the standard library Note, `time_checked_add` covers both `checked_add` and `checked_sub` --- ethcore/src/engines/authority_round/mod.rs | 11 ++++++----- ethcore/src/verification/verification.rs | 11 +++++++---- util/time-utils/src/lib.rs | 14 +------------- whisper/src/message.rs | 10 ++++++---- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index e6a0fac0f8d..babbf8102ad 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -42,12 +42,14 @@ use itertools::{self, Itertools}; use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp}; use ethereum_types::{H256, H520, Address, U128, U256}; use parking_lot::{Mutex, RwLock}; -use time_utils::CheckedSystemTime; use types::BlockNumber; use types::header::{Header, ExtendedHeader}; use types::ancestry_action::AncestryAction; use unexpected::{Mismatch, OutOfBounds}; +#[cfg(not(feature = "time_checked_add"))] +use time_utils::CheckedSystemTime; + mod finality; /// `AuthorityRound` params. @@ -577,10 +579,9 @@ fn verify_timestamp(step: &Step, header_step: u64) -> Result<(), BlockError> { trace!(target: "engine", "verify_timestamp: block too early"); let now = SystemTime::now(); - let found = CheckedSystemTime::checked_add(now, Duration::from_secs(oob.found)) - .ok_or(BlockError::TimestampOverflow)?; - let max = oob.max.and_then(|m| CheckedSystemTime::checked_add(now, Duration::from_secs(m))); - let min = oob.max.and_then(|m| CheckedSystemTime::checked_add(now, Duration::from_secs(m))); + let found = now.checked_add(Duration::from_secs(oob.found)).ok_or(BlockError::TimestampOverflow)?; + let max = oob.max.and_then(|m| now.checked_add(Duration::from_secs(m))); + let min = oob.min.and_then(|m| now.checked_add(Duration::from_secs(m))); let new_oob = OutOfBounds { min, max, found }; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 82812b0246c..37ab1977d77 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -36,11 +36,13 @@ use call_contract::CallContract; use client::BlockInfo; use engines::EthEngine; use error::{BlockError, Error}; -use time_utils::CheckedSystemTime; use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; use verification::queue::kind::blocks::Unverified; +#[cfg(not(feature = "time_checked_add"))] +use time_utils::CheckedSystemTime; + /// Preprocessed block data gathered in `verify_block_unordered` call pub struct PreverifiedBlock { /// Populated block header @@ -308,7 +310,7 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool, // this will resist overflow until `year 2037` let max_time = SystemTime::now() + ACCEPTABLE_DRIFT; let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9; - let timestamp = CheckedSystemTime::checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp())) + let timestamp = UNIX_EPOCH.checked_add(Duration::from_secs(header.timestamp())) .ok_or(BlockError::TimestampOverflow)?; if timestamp > invalid_threshold { @@ -331,9 +333,10 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result let gas_limit_divisor = engine.params().gas_limit_bound_divisor; if !engine.is_timestamp_valid(header.timestamp(), parent.timestamp()) { - let min = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_secs(parent.timestamp().saturating_add(1))) + let now = SystemTime::now(); + let min = now.checked_add(Duration::from_secs(parent.timestamp().saturating_add(1))) .ok_or(BlockError::TimestampOverflow)?; - let found = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_secs(header.timestamp())) + let found = now.checked_add(Duration::from_secs(header.timestamp())) .ok_or(BlockError::TimestampOverflow)?; return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found }))) } diff --git a/util/time-utils/src/lib.rs b/util/time-utils/src/lib.rs index 6af5424936b..ff9f159cfad 100644 --- a/util/time-utils/src/lib.rs +++ b/util/time-utils/src/lib.rs @@ -1,6 +1,6 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; -/// Temporary trait for `SystemTime::checked_add` until `Rust 1.33` is available +/// Temporary trait for `checked operations` on SystemTime until these are available in standard library pub trait CheckedSystemTime { /// Returns `Some` when the result less or equal to `i32::max_value` to prevent `SystemTime` to panic because /// it is platform specific, possible representations are i32, i64, u64 and Duration. `None` otherwise @@ -33,18 +33,6 @@ impl CheckedSystemTime for SystemTime { } } -/// Temporary trait for `Duration::as_millis` until `Rust 1.33` is available -pub trait AsMillis { - /// Duration represented as milliseconds - fn as_millis(&self) -> u128; -} - -impl AsMillis for Duration { - fn as_millis(&self) -> u128 { - self.as_secs() as u128 * 1_000 + (self.subsec_nanos() / 1_000_000) as u128 - } -} - #[cfg(test)] mod tests { #[test] diff --git a/whisper/src/message.rs b/whisper/src/message.rs index 3cd2bf9300f..613a9ee71ea 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -23,6 +23,8 @@ use ethereum_types::{H256, H512}; use rlp::{self, DecoderError, RlpStream, Rlp}; use smallvec::SmallVec; use tiny_keccak::{keccak256, Keccak}; + +#[cfg(not(feature = "time_checked_add"))] use time_utils::CheckedSystemTime; /// Work-factor proved. Takes 3 parameters: size of message, time to live, @@ -269,8 +271,8 @@ impl Message { assert!(params.ttl > 0); let expiry = { - let after_mining = CheckedSystemTime::checked_add(SystemTime::now(), Duration::from_millis(params.work)). - ok_or(Error::TimestampOverflow)?; + let after_mining = SystemTime::now().checked_sub(Duration::from_millis(params.work)) + .ok_or(Error::TimestampOverflow)?; let since_epoch = after_mining.duration_since(time::UNIX_EPOCH) .expect("time after now is after unix epoch; qed"); @@ -357,7 +359,7 @@ impl Message { (envelope.expiry - envelope.ttl).saturating_sub(LEEWAY_SECONDS) ); - let issue_time_adjusted = CheckedSystemTime::checked_add(time::UNIX_EPOCH, issue_time_adjusted) + let issue_time_adjusted = time::UNIX_EPOCH.checked_add(issue_time_adjusted) .ok_or(Error::TimestampOverflow)?; if issue_time_adjusted > now { @@ -404,7 +406,7 @@ impl Message { /// Get the expiry time. pub fn expiry(&self) -> Option { - CheckedSystemTime::checked_add(time::UNIX_EPOCH, Duration::from_secs(self.envelope.expiry)) + time::UNIX_EPOCH.checked_add(Duration::from_secs(self.envelope.expiry)) } /// Get the topics. From 4e07fea4be17fb9bcf01f85f69b36533250a3c37 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 14 Mar 2019 16:27:14 +0100 Subject: [PATCH 4/4] fix(grumble): use cfg_attr to define rustc feature --- ethcore/src/engines/authority_round/mod.rs | 2 +- ethcore/src/lib.rs | 5 ++++- ethcore/src/verification/verification.rs | 2 +- whisper/src/lib.rs | 6 +++++- whisper/src/message.rs | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index babbf8102ad..b973103e1e7 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -47,7 +47,7 @@ use types::header::{Header, ExtendedHeader}; use types::ancestry_action::AncestryAction; use unexpected::{Mismatch, OutOfBounds}; -#[cfg(not(feature = "time_checked_add"))] +#[cfg(not(time_checked_add))] use time_utils::CheckedSystemTime; mod finality; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 6578d360714..eee076b32ea 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -15,6 +15,7 @@ // along with Parity Ethereum. If not, see . #![warn(missing_docs, unused_extern_crates)] +#![cfg_attr(feature = "time_checked_add", feature(time_checked_add))] //! Ethcore library //! @@ -99,7 +100,6 @@ extern crate rlp; extern crate rustc_hex; extern crate serde; extern crate stats; -extern crate time_utils; extern crate triehash_ethereum as triehash; extern crate unexpected; extern crate using_queue; @@ -149,6 +149,9 @@ extern crate fetch; #[cfg(all(test, feature = "price-info"))] extern crate parity_runtime; +#[cfg(not(time_checked_add))] +extern crate time_utils; + pub mod block; pub mod builtin; pub mod client; diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 37ab1977d77..d5571198967 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -40,7 +40,7 @@ use types::{BlockNumber, header::Header}; use types::transaction::SignedTransaction; use verification::queue::kind::blocks::Unverified; -#[cfg(not(feature = "time_checked_add"))] +#[cfg(not(time_checked_add))] use time_utils::CheckedSystemTime; /// Preprocessed block data gathered in `verify_block_unordered` call diff --git a/whisper/src/lib.rs b/whisper/src/lib.rs index ee2c6d21362..cdc88780d4d 100644 --- a/whisper/src/lib.rs +++ b/whisper/src/lib.rs @@ -17,6 +17,8 @@ //! Whisper P2P messaging system as a DevP2P subprotocol, with RPC and Rust //! interface. +#![cfg_attr(feature = "time_checked_add", feature(time_checked_add))] + extern crate byteorder; extern crate parity_crypto as crypto; extern crate ethcore_network as network; @@ -32,7 +34,6 @@ extern crate serde; extern crate slab; extern crate smallvec; extern crate tiny_keccak; -extern crate time_utils; extern crate jsonrpc_core; extern crate jsonrpc_derive; @@ -47,6 +48,9 @@ extern crate log; #[macro_use] extern crate serde_derive; +#[cfg(not(time_checked_add))] +extern crate time_utils; + #[cfg(test)] extern crate serde_json; diff --git a/whisper/src/message.rs b/whisper/src/message.rs index 613a9ee71ea..0fc686e52a8 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -24,7 +24,7 @@ use rlp::{self, DecoderError, RlpStream, Rlp}; use smallvec::SmallVec; use tiny_keccak::{keccak256, Keccak}; -#[cfg(not(feature = "time_checked_add"))] +#[cfg(not(time_checked_add))] use time_utils::CheckedSystemTime; /// Work-factor proved. Takes 3 parameters: size of message, time to live,