New Transaction Queue implementation (#8074)

* Implementation of Verifier, Scoring and Ready.

* Queue in progress.

* TransactionPool.

* Prepare for txpool release.

* Miner refactor [WiP]

* WiP reworking miner.

* Make it compile.

* Add some docs.

* Split blockchain access to a separate file.

* Work on miner API.

* Fix ethcore tests.

* Refactor miner interface for sealing/work packages.

* Implement next nonce.

* RPC compiles.

* Implement couple of missing methdods for RPC.

* Add transaction queue listeners.

* Compiles!

* Clean-up and parallelize.

* Get rid of RefCell in header.

* Revert "Get rid of RefCell in header."

This reverts commit 0f2424c9b7319a786e1565ea2a8a6d801a21b4fb.

* Override Sync requirement.

* Fix status display.

* Unify logging.

* Extract some cheap checks.

* Measurements and optimizations.

* Fix scoring bug, heap size of bug and add cache

* Disable tx queueing and parallel verification.

* Make ethcore and ethcore-miner compile again.

* Make RPC compile again.

* Bunch of txpool tests.

* Migrate transaction queue tests.

* Nonce Cap

* Nonce cap cache and tests.

* Remove stale future transactions from the queue.

* Optimize scoring and write some tests.

* Simple penalization.

* Clean up and support for different scoring algorithms.

* Add CLI parameters for the new queue.

* Remove banning queue.

* Disable debug build.

* Change per_sender limit to be 1% instead of 5%

* Avoid cloning when propagating transactions.

* Remove old todo.

* Post-review fixes.

* Fix miner options default.

* Implement back ready transactions for light client.

* Get rid of from_pending_block

* Pass rejection reason.

* Add more details to drop.

* Rollback heap size of.

* Avoid cloning hashes when propagating and include more details on rejection.

* Fix tests.

* Introduce nonces cache.

* Remove uneccessary hashes allocation.

* Lower the mem limit.

* Re-enable parallel verification.

* Add miner log. Don't check the type if not below min_gas_price.

* Add more traces, fix disabling miner.

* Fix creating pending blocks twice on AuRa authorities.

* Fix tests.

* re-use pending blocks in AuRa

* Use reseal_min_period to prevent too frequent update_sealing.

* Fix log to contain hash not sender.

* Optimize local transactions.

* Fix aura tests.

* Update locks comments.

* Get rid of unsafe Sync impl.

* Review fixes.

* Remove excessive matches.

* Fix compilation errors.

* Use new pool in private transactions.

* Fix private-tx test.

* Fix secret store tests.

* Actually use gas_floor_target

* Fix config tests.

* Fix pool tests.

* Address grumbles.
This commit is contained in:
Tomasz Drwięga
2018-04-13 17:34:27 +02:00
committed by Marek Kotewicz
parent 03b96a7c0a
commit 1cd93e4ceb
105 changed files with 5185 additions and 5784 deletions

View File

@@ -26,13 +26,12 @@ use parking_lot::Mutex;
use ethash::SeedHashCompute;
use ethcore::account_provider::{AccountProvider, DappId};
use ethcore::block::IsBlock;
use ethcore::client::{MiningBlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo};
use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo};
use ethcore::ethereum::Ethash;
use ethcore::filter::Filter as EthcoreFilter;
use ethcore::header::{BlockNumber as EthBlockNumber};
use ethcore::log_entry::LogEntry;
use ethcore::miner::MinerService;
use ethcore::miner::{self, MinerService};
use ethcore::snapshot::SnapshotService;
use ethcore::encoded;
use sync::{SyncProvider};
@@ -92,7 +91,7 @@ impl Default for EthClientOptions {
/// Eth rpc implementation.
pub struct EthClient<C, SN: ?Sized, S: ?Sized, M, EM> where
C: MiningBlockChainClient,
C: miner::BlockChainClient + BlockChainClient,
SN: SnapshotService,
S: SyncProvider,
M: MinerService,
@@ -142,7 +141,7 @@ enum PendingTransactionId {
}
impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S, M, EM> where
C: MiningBlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo,
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo,
SN: SnapshotService,
S: SyncProvider,
M: MinerService<State=T>,
@@ -420,7 +419,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> EthClient<C, SN, S
}
pub fn pending_logs<M>(miner: &M, best_block: EthBlockNumber, filter: &EthcoreFilter) -> Vec<Log> where M: MinerService {
let receipts = miner.pending_receipts(best_block);
let receipts = miner.pending_receipts(best_block).unwrap_or_default();
let pending_logs = receipts.into_iter()
.flat_map(|(hash, r)| r.logs.into_iter().map(|l| (hash.clone(), l)).collect::<Vec<(H256, LogEntry)>>())
@@ -438,7 +437,7 @@ pub fn pending_logs<M>(miner: &M, best_block: EthBlockNumber, filter: &EthcoreFi
result
}
fn check_known<C>(client: &C, number: BlockNumber) -> Result<()> where C: MiningBlockChainClient {
fn check_known<C>(client: &C, number: BlockNumber) -> Result<()> where C: BlockChainClient {
use ethcore::block_status::BlockStatus;
let id = match number {
@@ -458,7 +457,7 @@ fn check_known<C>(client: &C, number: BlockNumber) -> Result<()> where C: Mining
const MAX_QUEUE_SIZE_TO_MINE_ON: usize = 4; // because uncles go back 6.
impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<C, SN, S, M, EM> where
C: MiningBlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo + 'static,
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo + 'static,
SN: SnapshotService + 'static,
S: SyncProvider + 'static,
M: MinerService<State=T> + 'static,
@@ -506,7 +505,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
fn author(&self, meta: Metadata) -> Result<RpcH160> {
let dapp = meta.dapp_id();
let mut miner = self.miner.author();
let mut miner = self.miner.authoring_params().author;
if miner == 0.into() {
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
}
@@ -571,16 +570,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
let res = match num.unwrap_or_default() {
BlockNumber::Pending if self.options.pending_nonce_from_queue => {
let nonce = self.miner.last_nonce(&address)
.map(|n| n + 1.into())
.or_else(|| self.client.nonce(&address, BlockId::Latest));
match nonce {
Some(nonce) => Ok(nonce.into()),
None => Err(errors::database("latest nonce missing"))
}
},
Ok(self.miner.next_nonce(&*self.client, &address).into())
}
BlockNumber::Pending => {
let info = self.client.chain_info();
let nonce = self.miner
@@ -596,7 +587,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
None => Err(errors::database("latest nonce missing"))
}
},
number => {
try_bf!(check_known(&*self.client, number.clone()));
match self.client.nonce(&address, block_number_to_id(number)) {
@@ -615,13 +605,13 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
}
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>> {
let block_number = self.client.chain_info().best_block_number;
Box::new(future::ok(match num {
BlockNumber::Pending => Some(
self.miner.status().transactions_in_pending_block.into()
),
BlockNumber::Pending =>
self.miner.pending_transactions(block_number).map(|x| x.len().into()),
_ =>
self.client.block(block_number_to_id(num))
.map(|block| block.transactions_count().into())
self.client.block(block_number_to_id(num)).map(|block| block.transactions_count().into())
}))
}
@@ -665,8 +655,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
let hash: H256 = hash.into();
let block_number = self.client.chain_info().best_block_number;
let tx = try_bf!(self.transaction(PendingTransactionId::Hash(hash))).or_else(|| {
self.miner.transaction(block_number, &hash)
.map(|t| Transaction::from_pending(t, block_number, self.eip86_transition))
self.miner.transaction(&hash)
.map(|t| Transaction::from_pending(t.pending().clone(), block_number + 1, self.eip86_transition))
});
Box::new(future::ok(tx))
@@ -745,11 +735,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
}
fn work(&self, no_new_work_timeout: Trailing<u64>) -> Result<Work> {
if !self.miner.can_produce_work_package() {
warn!(target: "miner", "Cannot give work package - engine seals internally.");
return Err(errors::no_work_required())
}
let no_new_work_timeout = no_new_work_timeout.unwrap_or_default();
// check if we're still syncing and return empty strings in that case
@@ -768,50 +753,58 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
}
}
if self.miner.author().is_zero() {
if self.miner.authoring_params().author.is_zero() {
warn!(target: "miner", "Cannot give work package - no author is configured. Use --author to configure!");
return Err(errors::no_author())
}
self.miner.map_sealing_work(&*self.client, |b| {
let pow_hash = b.hash();
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
let seed_hash = self.seed_compute.lock().hash_block_number(b.block().header().number());
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
if no_new_work_timeout > 0 && b.block().header().timestamp() + no_new_work_timeout < now {
Err(errors::no_new_work())
} else if self.options.send_block_number_in_get_work {
let block_number = b.block().header().number();
Ok(Work {
pow_hash: pow_hash.into(),
seed_hash: seed_hash.into(),
target: target.into(),
number: Some(block_number),
})
} else {
Ok(Work {
pow_hash: pow_hash.into(),
seed_hash: seed_hash.into(),
target: target.into(),
number: None
})
}
}).unwrap_or(Err(errors::internal("No work found.", "")))
let work = self.miner.work_package(&*self.client).ok_or_else(|| {
warn!(target: "miner", "Cannot give work package - engine seals internally.");
errors::no_work_required()
})?;
let (pow_hash, number, timestamp, difficulty) = work;
let target = Ethash::difficulty_to_boundary(&difficulty);
let seed_hash = self.seed_compute.lock().hash_block_number(number);
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
if no_new_work_timeout > 0 && timestamp + no_new_work_timeout < now {
Err(errors::no_new_work())
} else if self.options.send_block_number_in_get_work {
Ok(Work {
pow_hash: pow_hash.into(),
seed_hash: seed_hash.into(),
target: target.into(),
number: Some(number),
})
} else {
Ok(Work {
pow_hash: pow_hash.into(),
seed_hash: seed_hash.into(),
target: target.into(),
number: None
})
}
}
fn submit_work(&self, nonce: RpcH64, pow_hash: RpcH256, mix_hash: RpcH256) -> Result<bool> {
if !self.miner.can_produce_work_package() {
warn!(target: "miner", "Cannot submit work - engine seals internally.");
return Err(errors::no_work_required())
}
// TODO [ToDr] Should disallow submissions in case of PoA?
let nonce: H64 = nonce.into();
let pow_hash: H256 = pow_hash.into();
let mix_hash: H256 = mix_hash.into();
trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
let seal = vec![rlp::encode(&mix_hash).into_vec(), rlp::encode(&nonce).into_vec()];
Ok(self.miner.submit_seal(&*self.client, pow_hash, seal).is_ok())
let import = self.miner.submit_seal(pow_hash, seal)
.and_then(|block| self.client.import_sealed_block(block));
match import {
Ok(_) => Ok(true),
Err(err) => {
warn!(target: "miner", "Cannot submit work - {:?}.", err);
Ok(false)
},
}
}
fn submit_hashrate(&self, rate: RpcU256, id: RpcH256) -> Result<bool> {

View File

@@ -19,7 +19,7 @@
use std::sync::Arc;
use std::collections::HashSet;
use ethcore::miner::MinerService;
use ethcore::miner::{self, MinerService};
use ethcore::filter::Filter as EthcoreFilter;
use ethcore::client::{BlockChainClient, BlockId};
use ethereum_types::H256;
@@ -42,7 +42,7 @@ pub trait Filterable {
fn block_hash(&self, id: BlockId) -> Option<RpcH256>;
/// pending transaction hashes at the given block.
fn pending_transactions_hashes(&self, block_number: u64) -> Vec<H256>;
fn pending_transactions_hashes(&self) -> Vec<H256>;
/// Get logs that match the given filter.
fn logs(&self, filter: EthcoreFilter) -> BoxFuture<Vec<Log>>;
@@ -55,16 +55,13 @@ pub trait Filterable {
}
/// Eth filter rpc implementation for a full node.
pub struct EthFilterClient<C, M> where
C: BlockChainClient,
M: MinerService {
pub struct EthFilterClient<C, M> {
client: Arc<C>,
miner: Arc<M>,
polls: Mutex<PollManager<PollFilter>>,
}
impl<C, M> EthFilterClient<C, M> where C: BlockChainClient, M: MinerService {
impl<C, M> EthFilterClient<C, M> {
/// Creates new Eth filter client.
pub fn new(client: Arc<C>, miner: Arc<M>) -> Self {
EthFilterClient {
@@ -75,7 +72,10 @@ impl<C, M> EthFilterClient<C, M> where C: BlockChainClient, M: MinerService {
}
}
impl<C, M> Filterable for EthFilterClient<C, M> where C: BlockChainClient, M: MinerService {
impl<C, M> Filterable for EthFilterClient<C, M> where
C: miner::BlockChainClient + BlockChainClient,
M: MinerService,
{
fn best_block_number(&self) -> u64 {
self.client.chain_info().best_block_number
}
@@ -84,8 +84,11 @@ impl<C, M> Filterable for EthFilterClient<C, M> where C: BlockChainClient, M: Mi
self.client.block_hash(id).map(Into::into)
}
fn pending_transactions_hashes(&self, best: u64) -> Vec<H256> {
self.miner.pending_transactions_hashes(best)
fn pending_transactions_hashes(&self) -> Vec<H256> {
self.miner.ready_transactions(&*self.client)
.into_iter()
.map(|tx| tx.signed().hash())
.collect()
}
fn logs(&self, filter: EthcoreFilter) -> BoxFuture<Vec<Log>> {
@@ -118,8 +121,7 @@ impl<T: Filterable + Send + Sync + 'static> EthFilter for T {
fn new_pending_transaction_filter(&self) -> Result<RpcU256> {
let mut polls = self.polls().lock();
let best_block = self.best_block_number();
let pending_transactions = self.pending_transactions_hashes(best_block);
let pending_transactions = self.pending_transactions_hashes();
let id = polls.create_poll(PollFilter::PendingTransaction(pending_transactions));
Ok(id.into())
}
@@ -143,8 +145,7 @@ impl<T: Filterable + Send + Sync + 'static> EthFilter for T {
},
PollFilter::PendingTransaction(ref mut previous_hashes) => {
// get hashes of pending transactions
let best_block = self.best_block_number();
let current_hashes = self.pending_transactions_hashes(best_block);
let current_hashes = self.pending_transactions_hashes();
let new_hashes =
{

View File

@@ -533,7 +533,7 @@ impl<T: LightChainClient + 'static> Filterable for EthClient<T> {
self.client.block_hash(id).map(Into::into)
}
fn pending_transactions_hashes(&self, _block_number: u64) -> Vec<::ethereum_types::H256> {
fn pending_transactions_hashes(&self) -> Vec<::ethereum_types::H256> {
Vec::new()
}

View File

@@ -275,6 +275,21 @@ impl Parity for ParityClient {
)
}
fn all_transactions(&self) -> Result<Vec<Transaction>> {
let txq = self.light_dispatch.transaction_queue.read();
let chain_info = self.light_dispatch.client.chain_info();
let current = txq.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp);
let future = txq.future_transactions(chain_info.best_block_number, chain_info.best_block_timestamp);
Ok(
current
.into_iter()
.chain(future.into_iter())
.map(|tx| Transaction::from_pending(tx, chain_info.best_block_number, self.eip86_transition))
.collect::<Vec<_>>()
)
}
fn future_transactions(&self) -> Result<Vec<Transaction>> {
let txq = self.light_dispatch.transaction_queue.read();
let chain_info = self.light_dispatch.client.chain_info();

View File

@@ -27,9 +27,9 @@ use ethkey::{Brain, Generator};
use ethstore::random_phrase;
use sync::{SyncProvider, ManageNetwork};
use ethcore::account_provider::AccountProvider;
use ethcore::client::{MiningBlockChainClient, StateClient, Call};
use ethcore::client::{BlockChainClient, StateClient, Call};
use ethcore::ids::BlockId;
use ethcore::miner::MinerService;
use ethcore::miner::{self, MinerService};
use ethcore::mode::Mode;
use ethcore::state::StateInfo;
use ethcore_logger::RotatingLogger;
@@ -72,7 +72,7 @@ pub struct ParityClient<C, M, U> {
}
impl<C, M, U> ParityClient<C, M, U> where
C: MiningBlockChainClient,
C: BlockChainClient,
{
/// Creates new `ParityClient`.
pub fn new(
@@ -116,7 +116,7 @@ impl<C, M, U> ParityClient<C, M, U> where
impl<C, M, U, S> Parity for ParityClient<C, M, U> where
S: StateInfo + 'static,
C: MiningBlockChainClient + StateClient<State=S> + Call<State=S> + 'static,
C: miner::BlockChainClient + BlockChainClient + StateClient<State=S> + Call<State=S> + 'static,
M: MinerService<State=S> + 'static,
U: UpdateService + 'static,
{
@@ -170,23 +170,23 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
}
fn transactions_limit(&self) -> Result<usize> {
Ok(self.miner.transactions_limit())
Ok(self.miner.queue_status().limits.max_count)
}
fn min_gas_price(&self) -> Result<U256> {
Ok(U256::from(self.miner.minimal_gas_price()))
Ok(self.miner.queue_status().options.minimal_gas_price.into())
}
fn extra_data(&self) -> Result<Bytes> {
Ok(Bytes::new(self.miner.extra_data()))
Ok(Bytes::new(self.miner.authoring_params().extra_data))
}
fn gas_floor_target(&self) -> Result<U256> {
Ok(U256::from(self.miner.gas_floor_target()))
Ok(U256::from(self.miner.authoring_params().gas_range_target.0))
}
fn gas_ceil_target(&self) -> Result<U256> {
Ok(U256::from(self.miner.gas_ceil_target()))
Ok(U256::from(self.miner.authoring_params().gas_range_target.1))
}
fn dev_logs(&self) -> Result<Vec<String>> {
@@ -315,12 +315,28 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
fn pending_transactions(&self) -> Result<Vec<Transaction>> {
let block_number = self.client.chain_info().best_block_number;
Ok(self.miner.pending_transactions().into_iter().map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)).collect::<Vec<_>>())
let ready_transactions = self.miner.ready_transactions(&*self.client);
Ok(ready_transactions
.into_iter()
.map(|t| Transaction::from_pending(t.pending().clone(), block_number, self.eip86_transition))
.collect()
)
}
fn all_transactions(&self) -> Result<Vec<Transaction>> {
let block_number = self.client.chain_info().best_block_number;
let all_transactions = self.miner.queued_transactions();
Ok(all_transactions
.into_iter()
.map(|t| Transaction::from_pending(t.pending().clone(), block_number, self.eip86_transition))
.collect()
)
}
fn future_transactions(&self) -> Result<Vec<Transaction>> {
let block_number = self.client.chain_info().best_block_number;
Ok(self.miner.future_transactions().into_iter().map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)).collect::<Vec<_>>())
Err(errors::deprecated("Use `parity_allTransaction` instead."))
}
fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>> {
@@ -359,11 +375,7 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
fn next_nonce(&self, address: H160) -> BoxFuture<U256> {
let address: Address = address.into();
Box::new(future::ok(self.miner.last_nonce(&address)
.map(|n| n + 1.into())
.unwrap_or_else(|| self.client.latest_nonce(&address))
.into()
))
Box::new(future::ok(self.miner.next_nonce(&*self.client, &address).into()))
}
fn mode(&self) -> Result<String> {

View File

@@ -18,8 +18,8 @@
use std::io;
use std::sync::Arc;
use ethcore::client::BlockChainClient;
use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use ethcore::mode::Mode;
use sync::ManageNetwork;
use fetch::{self, Fetch};
@@ -47,7 +47,7 @@ pub struct ParitySetClient<C, M, U, F = fetch::Client> {
}
impl<C, M, U, F> ParitySetClient<C, M, U, F>
where C: MiningBlockChainClient + 'static,
where C: BlockChainClient + 'static,
{
/// Creates new `ParitySetClient` with given `Fetch`.
pub fn new(
@@ -73,24 +73,38 @@ impl<C, M, U, F> ParitySetClient<C, M, U, F>
}
impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
C: MiningBlockChainClient + 'static,
C: BlockChainClient + 'static,
M: MinerService + 'static,
U: UpdateService + 'static,
F: Fetch + 'static,
{
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool> {
self.miner.set_minimal_gas_price(gas_price.into());
Ok(true)
fn set_min_gas_price(&self, _gas_price: U256) -> Result<bool> {
warn!("setMinGasPrice is deprecated. Ignoring request.");
Ok(false)
}
fn set_transactions_limit(&self, _limit: usize) -> Result<bool> {
warn!("setTransactionsLimit is deprecated. Ignoring request.");
Ok(false)
}
fn set_tx_gas_limit(&self, _limit: U256) -> Result<bool> {
warn!("setTxGasLimit is deprecated. Ignoring request.");
Ok(false)
}
fn set_gas_floor_target(&self, target: U256) -> Result<bool> {
self.miner.set_gas_floor_target(target.into());
let mut range = self.miner.authoring_params().gas_range_target.clone();
range.0 = target.into();
self.miner.set_gas_range_target(range);
Ok(true)
}
fn set_gas_ceil_target(&self, target: U256) -> Result<bool> {
self.miner.set_gas_ceil_target(target.into());
let mut range = self.miner.authoring_params().gas_range_target.clone();
range.1 = target.into();
self.miner.set_gas_range_target(range);
Ok(true)
}
@@ -99,23 +113,13 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
Ok(true)
}
fn set_author(&self, author: H160) -> Result<bool> {
self.miner.set_author(author.into());
fn set_author(&self, address: H160) -> Result<bool> {
self.miner.set_author(address.into(), None).map_err(Into::into).map_err(errors::password)?;
Ok(true)
}
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool> {
self.miner.set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::password)?;
Ok(true)
}
fn set_transactions_limit(&self, limit: usize) -> Result<bool> {
self.miner.set_transactions_limit(limit);
Ok(true)
}
fn set_tx_gas_limit(&self, limit: U256) -> Result<bool> {
self.miner.set_tx_gas_limit(limit.into());
self.miner.set_author(address.into(), Some(password)).map_err(Into::into).map_err(errors::password)?;
Ok(true)
}
@@ -202,6 +206,8 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
let block_number = self.client.chain_info().best_block_number;
let hash = hash.into();
Ok(self.miner.remove_pending_transaction(&*self.client, &hash).map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)))
Ok(self.miner.remove_transaction(&hash)
.map(|t| Transaction::from_pending(t.pending().clone(), block_number + 1, self.eip86_transition))
)
}
}

View File

@@ -18,7 +18,7 @@
use std::sync::Arc;
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId};
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId};
use rlp::UntrustedRlp;
use transaction::SignedTransaction;
@@ -53,7 +53,7 @@ impl<C> TracesClient<C> {
impl<C, S> Traces for TracesClient<C> where
S: StateInfo + 'static,
C: MiningBlockChainClient + StateClient<State=S> + Call<State=S> + 'static
C: BlockChainClient + StateClient<State=S> + Call<State=S> + 'static
{
type Metadata = Metadata;