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:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
|
||||
|
||||
@@ -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")) }
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
@@ -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> {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user