Backports for Beta 2.3.3 (#10333)

* version: bump beta to 2.3.3

* import rpc transactions sequentially (#10051)

* import rpc transactions sequentially

* use impl trait in argument position, renamed ProspectiveDispatcher to WithPostSign

* grouped imports

* integrates PostSign with ProspectiveSigner

* fix spaces, removed unnecessary type cast and duplicate polling

* clean up code style

* Apply suggestions from code review

* Fix Windows build (#10284)

* Don't run the CPP example on CI (#10285)

* Don't run the CPP example on CI

* Add comment

* CI optimizations (#10297)

* CI optimizations

* fix stripping

* new dockerfile

* no need n submodule upd

* review

* moved dockerfile

* it becomes large

* onchain update depends on s3

* fix dependency

* fix cache status

* fix cache status

* new cache status

* fix publish job (#10317)

* fix publish job

* dashes and colonels

* Add Statetest support for Constantinople Fix (#10323)

* Update Ethereum tests repo to v6.0.0-beta.3 tag

* Add spec for St.Peter's / ConstantinopleFix statetests

* Properly handle check_epoch_end_signal errors (#10015)

* Make check_epoch_end_signal to only use immutable data

* Move check_epoch_end_signals out of commit_block

* Make check_epoch_end_signals possible to fail

* Actually return the error from check_epoch_end_signals

* Remove a clone

* Fix import error

* cargo: fix compilation

* fix(add helper for timestamp overflows) (#10330)

* fix(add helper timestamp overflows)

* fix(simplify code)

* fix(make helper private)

* Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205)

* Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client`

* Remove CallContract and RegistryInfo re-exports again

This was missed while fixing merge conflicts

* fix(docker): fix not receives SIGINT (#10059)

* fix(docker): fix not receives SIGINT

* fix: update with reviews

* update with review

* update

* update

* snap: official image / test (#10168)

* official image / test

* fix / test

* bit more necromancy

* fix paths

* add source bin/df /test

* add source bin/df /test2

* something w paths /test

* something w paths /test

* add source-type /test

* show paths /test

* copy plugin /test

* plugin -> nil

* install rhash

* no questions while installing rhash

* publish snap only for release

* Don't add discovery initiators to the node table (#10305)

* Don't add discovery initiators to the node table

* Use enums for tracking state of the nodes in discovery

* Dont try to ping ourselves

* Fix minor nits

* Update timeouts when observing an outdated node

* Extracted update_bucket_record from update_node

* Fixed typo

* Fix two final nits from @todr

* Extract CallContract and RegistryInfo traits into their own crate (#10178)

* Create call-contract crate

* Add license

* First attempt at using extracted CallContract trait

* Remove unneeded `extern crate` calls

* Move RegistryInfo trait into call-contract crate

* Move service-transaction-checker from ethcore to ethcore-miner

* Update Cargo.lock file

* Re-export call_contract

* Merge CallContract and RegistryInfo imports

* Remove commented code

* Add documentation to call_contract crate

* Add TODO for removal of re-exports

* Update call-contract crate description

Co-Authored-By: HCastano <HCastano@users.noreply.github.com>

* Rename call-contract crate to ethcore-call-contract

* Remove CallContract and RegistryInfo re-exports from `ethcore/client` (#10205)

* Remove re-export of `CallContract` and `RegistryInfo` from `ethcore/client`

* Remove CallContract and RegistryInfo re-exports again

This was missed while fixing merge conflicts

* fixed: types::transaction::SignedTransaction; (#10229)

* fix daemonize dependency

* fix build

* change docker image based on debian instead of ubuntu due to the chan… (#10336)

* change docker image based on debian instead of ubuntu due to the changes of the build container

* role back docker build image and docker deploy image to ubuntu:xenial based (#10338)

* perform stripping during build (#10208)

* perform stripping during build (#10208)

* perform stripping during build

* var RUSTFLAGS
This commit is contained in:
Afri Schoedon
2019-02-13 11:00:41 +01:00
committed by GitHub
parent a6c4b17303
commit 3b9b1a8f14
60 changed files with 690 additions and 303 deletions

View File

@@ -23,6 +23,7 @@ use std::time::{Instant, Duration};
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
use bytes::Bytes;
use call_contract::{CallContract, RegistryInfo};
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{H256, Address, U256};
use evm::Schedule;
@@ -46,8 +47,8 @@ use vm::{EnvInfo, LastHashes};
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
use client::ancient_import::AncientVerifier;
use client::{
Nonce, Balance, ChainInfo, BlockInfo, CallContract, TransactionInfo,
RegistryInfo, ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
Nonce, Balance, ChainInfo, BlockInfo, TransactionInfo,
ReopenBlock, PrepareOpenBlock, ScheduleInfo, ImportSealedBlock,
BroadcastProposalBlock, ImportBlock, StateOrBlock, StateInfo, StateClient, Call,
AccountData, BlockChain as BlockChainTrait, BlockProducer, SealedBlockImporter,
ClientIoMessage,
@@ -59,7 +60,8 @@ use client::{
IoClient, BadBlocks,
};
use client::bad_blocks;
use engines::{EthEngine, EpochTransition, ForkChoice};
use engines::{EthEngine, EpochTransition, ForkChoice, EngineError};
use engines::epoch::PendingTransition;
use error::{
ImportErrorKind, ExecutionError, CallError, BlockError,
QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult, ErrorKind as EthcoreErrorKind
@@ -291,8 +293,8 @@ impl Importer {
continue;
}
match self.check_and_lock_block(block, client) {
Ok(closed_block) => {
match self.check_and_lock_block(&bytes, block, client) {
Ok((closed_block, pending)) => {
if self.engine.is_proposal(&header) {
self.block_queue.mark_as_good(&[hash]);
proposed_blocks.push(bytes);
@@ -301,7 +303,7 @@ impl Importer {
let transactions_len = closed_block.transactions().len();
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), client);
let route = self.commit_block(closed_block, &header, encoded::Block::new(bytes), pending, client);
import_results.push(route);
client.report.write().accrue_block(&header, transactions_len);
@@ -353,7 +355,7 @@ impl Importer {
imported
}
fn check_and_lock_block(&self, block: PreverifiedBlock, client: &Client) -> EthcoreResult<LockedBlock> {
fn check_and_lock_block(&self, bytes: &[u8], block: PreverifiedBlock, client: &Client) -> EthcoreResult<(LockedBlock, Option<PendingTransition>)> {
let engine = &*self.engine;
let header = block.header.clone();
@@ -437,7 +439,15 @@ impl Importer {
bail!(e);
}
Ok(locked_block)
let pending = self.check_epoch_end_signal(
&header,
bytes,
locked_block.receipts(),
locked_block.state().db(),
client
)?;
Ok((locked_block, pending))
}
/// Import a block with transaction receipts.
@@ -469,7 +479,8 @@ impl Importer {
// it is for reconstructing the state transition.
//
// The header passed is from the original block data and is sealed.
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, client: &Client) -> ImportRoute where B: Drain {
// TODO: should return an error if ImportRoute is none, issue #9910
fn commit_block<B>(&self, block: B, header: &Header, block_data: encoded::Block, pending: Option<PendingTransition>, client: &Client) -> ImportRoute where B: Drain {
let hash = &header.hash();
let number = header.number();
let parent = header.parent_hash();
@@ -524,15 +535,9 @@ impl Importer {
// check epoch end signal, potentially generating a proof on the current
// state.
self.check_epoch_end_signal(
&header,
block_data.raw(),
&receipts,
&state,
&chain,
&mut batch,
client
);
if let Some(pending) = pending {
chain.insert_pending_transition(&mut batch, header.hash(), pending);
}
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
@@ -587,10 +592,8 @@ impl Importer {
block_bytes: &[u8],
receipts: &[Receipt],
state_db: &StateDB,
chain: &BlockChain,
batch: &mut DBTransaction,
client: &Client,
) {
) -> EthcoreResult<Option<PendingTransition>> {
use engines::EpochChange;
let hash = header.hash();
@@ -601,7 +604,6 @@ impl Importer {
match self.engine.signals_epoch_end(header, auxiliary) {
EpochChange::Yes(proof) => {
use engines::epoch::PendingTransition;
use engines::Proof;
let proof = match proof {
@@ -638,11 +640,9 @@ impl Importer {
.transact(&transaction, options);
let res = match res {
Err(ExecutionError::Internal(e)) =>
Err(format!("Internal error: {}", e)),
Err(e) => {
trace!(target: "client", "Proved call failed: {}", e);
Ok((Vec::new(), state.drop().1.extract_proof()))
Err(e.to_string())
}
Ok(res) => Ok((res.output, state.drop().1.extract_proof())),
};
@@ -655,7 +655,7 @@ impl Importer {
Err(e) => {
warn!(target: "client", "Failed to generate transition proof for block {}: {}", hash, e);
warn!(target: "client", "Snapshots produced by this client may be incomplete");
Vec::new()
return Err(EngineError::FailedSystemCall(e).into())
}
}
}
@@ -663,13 +663,13 @@ impl Importer {
debug!(target: "client", "Block {} signals epoch end.", hash);
let pending = PendingTransition { proof: proof };
chain.insert_pending_transition(batch, hash, pending);
Ok(Some(PendingTransition { proof: proof }))
},
EpochChange::No => {},
EpochChange::No => Ok(None),
EpochChange::Unsure(_) => {
warn!(target: "client", "Detected invalid engine implementation.");
warn!(target: "client", "Engine claims to require more block data, but everything provided.");
Err(EngineError::InvalidEngine.into())
}
}
}
@@ -2328,7 +2328,20 @@ impl ImportSealedBlock for Client {
let block_data = block.rlp_bytes();
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
let pending = self.importer.check_epoch_end_signal(
&header,
&block_data,
block.receipts(),
block.state().db(),
self
)?;
let route = self.importer.commit_block(
block,
&header,
encoded::Block::new(block_data),
pending,
self
);
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), hash);
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
route

View File

@@ -93,6 +93,7 @@ impl<'a> EvmTestClient<'a> {
ForkSpec::EIP158 => Some(ethereum::new_eip161_test()),
ForkSpec::Byzantium => Some(ethereum::new_byzantium_test()),
ForkSpec::Constantinople => Some(ethereum::new_constantinople_test()),
ForkSpec::ConstantinopleFix => Some(ethereum::new_constantinople_fix_test()),
ForkSpec::EIP158ToByzantiumAt5 => Some(ethereum::new_transition_test()),
ForkSpec::FrontierToHomesteadAt5 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => None,
}

View File

@@ -36,7 +36,7 @@ pub use self::io_message::ClientIoMessage;
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
pub use self::chain_notify::{ChainNotify, NewBlocks, ChainRoute, ChainRouteType, ChainMessageType};
pub use self::traits::{
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, TransactionInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, BadBlocks,
};
pub use state::StateInfo;

View File

@@ -49,8 +49,9 @@ use types::views::BlockView;
use vm::Schedule;
use block::{OpenBlock, SealedBlock, ClosedBlock};
use call_contract::{CallContract, RegistryInfo};
use client::{
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, CallContract, TransactionInfo, RegistryInfo,
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, TransactionInfo,
PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode,
TransactionId, UncleId, TraceId, TraceFilter, LastHashes, CallAnalytics,
ProvingBlockChainClient, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock, StateOrBlock,

View File

@@ -19,6 +19,7 @@ use std::sync::Arc;
use blockchain::{BlockReceipts, TreeRoute};
use bytes::Bytes;
use call_contract::{CallContract, RegistryInfo};
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{H256, U256, Address};
use evm::Schedule;
@@ -157,12 +158,6 @@ pub trait StateClient {
/// Provides various blockchain information, like block header, chain state etc.
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
/// Provides information on a blockchain service and it's registry
pub trait RegistryInfo {
/// Get the address of a particular blockchain service, if available.
fn registry_address(&self, name: String, block: BlockId) -> Option<Address>;
}
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
/// Provides methods to import block into blockchain
pub trait ImportBlock {
@@ -170,12 +165,6 @@ pub trait ImportBlock {
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
}
/// Provides `call_contract` method
pub trait CallContract {
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
}
/// Provides `call` and `call_many` methods
pub trait Call {
/// Type representing chain state

View File

@@ -81,6 +81,8 @@ pub enum EngineError {
MalformedMessage(String),
/// Requires client ref, but none registered.
RequiresClient,
/// Invalid engine specification or implementation.
InvalidEngine,
}
impl fmt::Display for EngineError {
@@ -96,6 +98,7 @@ impl fmt::Display for EngineError {
FailedSystemCall(ref msg) => format!("Failed to make system call: {}", msg),
MalformedMessage(ref msg) => format!("Received malformed consensus message: {}", msg),
RequiresClient => format!("Call requires client but none registered"),
InvalidEngine => format!("Invalid engine specification or implementation"),
};
f.write_fmt(format_args!("Engine error ({})", msg))

View File

@@ -145,7 +145,8 @@ mod tests {
use miner::MinerService;
use types::ids::BlockId;
use test_helpers::generate_dummy_client_with_spec_and_accounts;
use client::{BlockChainClient, ChainInfo, BlockInfo, CallContract};
use call_contract::CallContract;
use client::{BlockChainClient, ChainInfo, BlockInfo};
use super::super::ValidatorSet;
use super::ValidatorContract;

View File

@@ -90,6 +90,8 @@ pub enum BlockError {
InvalidNumber(Mismatch<BlockNumber>),
/// Block number isn't sensible.
RidiculousNumber(OutOfBounds<BlockNumber>),
/// Timestamp header overflowed
TimestampOverflow,
/// Too many transactions from a particular address.
TooManyTransactions(Address),
/// Parent given is unknown.
@@ -139,6 +141,7 @@ impl fmt::Display for BlockError {
UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash),
UnknownEpochTransition(ref num) => format!("Unknown transition to epoch number: {}", num),
TimestampOverflow => format!("Timestamp overflow"),
TooManyTransactions(ref address) => format!("Too many transactions from: {}", address),
};

View File

@@ -148,6 +148,9 @@ pub fn new_byzantium_test() -> Spec { load(None, include_bytes!("../../res/ether
/// Create a new Foundation Constantinople era spec.
pub fn new_constantinople_test() -> Spec { load(None, include_bytes!("../../res/ethereum/constantinople_test.json")) }
/// Create a new Foundation St. Peter's (Contantinople Fix) era spec.
pub fn new_constantinople_fix_test() -> Spec { load(None, include_bytes!("../../res/ethereum/st_peters_test.json")) }
/// Create a new Musicoin-MCIP3-era spec.
pub fn new_mcip3_test() -> Spec { load(None, include_bytes!("../../res/ethereum/mcip3_test.json")) }
@@ -168,6 +171,9 @@ pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_by
/// Create a new Foundation Constantinople era spec.
pub fn new_constantinople_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/constantinople_test.json")) }
/// Create a new Foundation St. Peter's (Contantinople Fix) era spec.
pub fn new_constantinople_fix_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/st_peters_test.json")) }
/// Create a new Musicoin-MCIP3-era spec.
pub fn new_mcip3_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/mcip3_test.json")) }

View File

@@ -165,6 +165,7 @@ mod state_tests {
declare_test!{GeneralStateTest_stRefundTest, "GeneralStateTests/stRefundTest/"}
declare_test!{GeneralStateTest_stReturnDataTest, "GeneralStateTests/stReturnDataTest/"}
declare_test!{GeneralStateTest_stRevertTest, "GeneralStateTests/stRevertTest/"}
declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"}
declare_test!{GeneralStateTest_stShift, "GeneralStateTests/stShift/"}
declare_test!{GeneralStateTest_stSolidityTest, "GeneralStateTests/stSolidityTest/"}
declare_test!{GeneralStateTest_stSpecialTest, "GeneralStateTests/stSpecialTest/"}
@@ -177,7 +178,6 @@ mod state_tests {
declare_test!{GeneralStateTest_stZeroCallsRevert, "GeneralStateTests/stZeroCallsRevert/"}
declare_test!{GeneralStateTest_stZeroCallsTest, "GeneralStateTests/stZeroCallsTest/"}
declare_test!{GeneralStateTest_stZeroKnowledge, "GeneralStateTests/stZeroKnowledge/"}
declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"}
// Attempts to send a transaction that requires more than current balance:
// Tx:

View File

@@ -66,6 +66,7 @@ extern crate ethabi;
extern crate ethash;
extern crate ethcore_blockchain as blockchain;
extern crate ethcore_bloom_journal as bloom_journal;
extern crate ethcore_call_contract as call_contract;
extern crate ethcore_db as db;
extern crate ethcore_io as io;
extern crate ethcore_miner;

View File

@@ -30,7 +30,8 @@ use vm::{EnvInfo, Schedule, CreateContractAddress};
use block::{ExecutedBlock, IsBlock};
use builtin::Builtin;
use client::{BlockInfo, CallContract};
use call_contract::CallContract;
use client::BlockInfo;
use error::Error;
use executive::Executive;
use spec::CommonParams;

View File

@@ -21,6 +21,7 @@ use std::sync::Arc;
use ansi_term::Colour;
use bytes::Bytes;
use call_contract::CallContract;
use ethcore_miner::gas_pricer::GasPricer;
use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy};
#[cfg(feature = "work-notify")]
@@ -48,7 +49,7 @@ use using_queue::{UsingQueue, GetAction};
use account_provider::{AccountProvider, SignError as AccountError};
use block::{ClosedBlock, IsBlock, SealedBlock};
use client::{
BlockChain, ChainInfo, CallContract, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
};
use client::{BlockId, ClientIoMessage};
use engines::{EthEngine, Seal};

View File

@@ -20,7 +20,6 @@
//! Keeps track of transactions and currently sealed pending block.
mod miner;
mod service_transaction_checker;
pub mod pool_client;
#[cfg(feature = "stratum")]
@@ -43,8 +42,9 @@ use types::header::Header;
use types::receipt::RichReceipt;
use block::SealedBlock;
use call_contract::{CallContract, RegistryInfo};
use client::{
CallContract, RegistryInfo, ScheduleInfo,
ScheduleInfo,
BlockChain, BlockProducer, SealedBlockImporter, ChainInfo,
AccountData, Nonce,
};

View File

@@ -25,6 +25,7 @@ use std::{
use ethereum_types::{H256, U256, Address};
use ethcore_miner::pool;
use ethcore_miner::pool::client::NonceClient;
use ethcore_miner::service_transaction_checker::ServiceTransactionChecker;
use types::transaction::{
self,
UnverifiedTransaction,
@@ -34,10 +35,10 @@ use types::header::Header;
use parking_lot::RwLock;
use account_provider::AccountProvider;
use client::{TransactionId, BlockInfo, CallContract, Nonce};
use call_contract::CallContract;
use client::{TransactionId, BlockInfo, Nonce};
use engines::EthEngine;
use miner;
use miner::service_transaction_checker::ServiceTransactionChecker;
use transaction_ext::Transaction;
/// Cache for state nonces.

View File

@@ -1,51 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! A service transactions contract checker.
use client::{RegistryInfo, CallContract, BlockId};
use types::transaction::SignedTransaction;
use ethabi::FunctionOutputDecoder;
use_contract!(service_transaction, "res/contracts/service_transaction.json");
const SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME: &'static str = "service_transaction_checker";
/// Service transactions checker.
#[derive(Default, Clone)]
pub struct ServiceTransactionChecker;
impl ServiceTransactionChecker {
/// Checks if given address is whitelisted to send service transactions.
pub fn check<C: CallContract + RegistryInfo>(&self, client: &C, tx: &SignedTransaction) -> Result<bool, String> {
let sender = tx.sender();
let hash = tx.hash();
// Skip checking the contract if the transaction does not have zero gas price
if !tx.gas_price.is_zero() {
return Ok(false)
}
let address = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest)
.ok_or_else(|| "contract is not configured")?;
trace!(target: "txqueue", "[{:?}] Checking service transaction checker contract from {}", hash, sender);
let (data, decoder) = service_transaction::functions::certified::call(sender);
let value = client.call_contract(BlockId::Latest, address, data)?;
decoder.decode(&value).map_err(|e| e.to_string())
}
}

View File

@@ -1289,6 +1289,13 @@ impl<B: Backend> fmt::Debug for State<B> {
}
}
impl State<StateDB> {
/// Get a reference to the underlying state DB.
pub fn db(&self) -> &StateDB {
&self.db
}
}
// TODO: cloning for `State` shouldn't be possible in general; Remove this and use
// checkpoints where possible.
impl Clone for State<StateDB> {

View File

@@ -20,7 +20,8 @@ use ethereum_types::{H256, U256, Address};
use lru_cache::LruCache;
use ethabi::FunctionOutputDecoder;
use client::{BlockInfo, CallContract, BlockId};
use call_contract::CallContract;
use client::{BlockInfo, BlockId};
use parking_lot::Mutex;
use spec::CommonParams;
use types::transaction::{Action, SignedTransaction};

View File

@@ -16,7 +16,8 @@
//! Canonical verifier.
use client::{BlockInfo, CallContract};
use call_contract::CallContract;
use client::BlockInfo;
use engines::EthEngine;
use error::Error;
use types::header::Header;

View File

@@ -28,7 +28,8 @@ pub use self::canon_verifier::CanonVerifier;
pub use self::noop_verifier::NoopVerifier;
pub use self::queue::{BlockQueue, Config as QueueConfig, VerificationQueue, QueueInfo};
use client::{BlockInfo, CallContract};
use call_contract::CallContract;
use client::BlockInfo;
/// Verifier type.
#[derive(Debug, PartialEq, Clone)]

View File

@@ -16,7 +16,8 @@
//! No-op verifier.
use client::{BlockInfo, CallContract};
use call_contract::CallContract;
use client::BlockInfo;
use engines::EthEngine;
use error::Error;
use types::header::Header;

View File

@@ -32,13 +32,33 @@ use triehash::ordered_trie_root;
use unexpected::{Mismatch, OutOfBounds};
use blockchain::*;
use client::{BlockInfo, CallContract};
use call_contract::CallContract;
use client::BlockInfo;
use engines::EthEngine;
use error::{BlockError, Error};
use types::{BlockNumber, header::Header};
use types::transaction::SignedTransaction;
use verification::queue::kind::blocks::Unverified;
/// Returns `Ok<SystemTime>` 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<BlockError::TimestampOver` otherwise.
///
// FIXME: @niklasad1 - remove this when and use `SystemTime::checked_add`
// when https://github.com/rust-lang/rust/issues/55940 is stabilized.
fn timestamp_checked_add(sys: SystemTime, d2: Duration) -> Result<SystemTime, BlockError> {
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
@@ -305,7 +325,7 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool,
const ACCEPTABLE_DRIFT: Duration = Duration::from_secs(15);
let max_time = SystemTime::now() + ACCEPTABLE_DRIFT;
let invalid_threshold = max_time + ACCEPTABLE_DRIFT * 9;
let timestamp = UNIX_EPOCH + Duration::from_secs(header.timestamp());
let timestamp = timestamp_checked_add(UNIX_EPOCH, Duration::from_secs(header.timestamp()))?;
if timestamp > invalid_threshold {
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: timestamp })))
@@ -327,8 +347,8 @@ 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 = SystemTime::now() + Duration::from_secs(parent.timestamp() + 1);
let found = SystemTime::now() + Duration::from_secs(header.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()))?;
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: None, min: Some(min), found })))
}
if header.number() != parent.number() + 1 {
@@ -742,7 +762,8 @@ mod tests {
check_fail_timestamp(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc), false);
header = good.clone();
header.set_timestamp(2450000000);
// will return `BlockError::TimestampOverflow` when timestamp > `i32::max_value()`
header.set_timestamp(i32::max_value() as u64);
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine), false);
header = good.clone();
@@ -814,4 +835,11 @@ 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());
}
}

View File

@@ -16,7 +16,8 @@
//! A generic verifier trait.
use client::{BlockInfo, CallContract};
use call_contract::CallContract;
use client::BlockInfo;
use engines::EthEngine;
use error::Error;
use types::header::Header;