Merge pull request #752 from ethcore/tx_queue_invalid
Removing transactions that failed to be pushed to block.
This commit is contained in:
commit
a1fb0619bb
@ -391,7 +391,8 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO [todr] Should be moved to miner crate eventually.
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> {
|
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
|
||||||
|
-> Option<(ClosedBlock, HashSet<H256>)> {
|
||||||
let engine = self.engine.deref().deref();
|
let engine = self.engine.deref().deref();
|
||||||
let h = self.chain.best_block_hash();
|
let h = self.chain.best_block_hash();
|
||||||
|
|
||||||
@ -417,21 +418,40 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
|||||||
|
|
||||||
// Add transactions
|
// Add transactions
|
||||||
let block_number = b.block().header().number();
|
let block_number = b.block().header().number();
|
||||||
|
let min_tx_gas = U256::from(self.engine.schedule(&b.env_info()).tx_gas);
|
||||||
|
let mut invalid_transactions = HashSet::new();
|
||||||
|
|
||||||
for tx in transactions {
|
for tx in transactions {
|
||||||
|
// Push transaction to block
|
||||||
|
let hash = tx.hash();
|
||||||
let import = b.push_transaction(tx, None);
|
let import = b.push_transaction(tx, None);
|
||||||
if let Err(e) = import {
|
|
||||||
trace!("Error adding transaction to block: number={}. Error: {:?}", block_number, e);
|
match import {
|
||||||
|
Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, .. })) => {
|
||||||
|
trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", hash);
|
||||||
|
// Exit early if gas left is smaller then min_tx_gas
|
||||||
|
if gas_limit - gas_used < min_tx_gas {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
invalid_transactions.insert(hash);
|
||||||
|
trace!(target: "miner",
|
||||||
|
"Error adding transaction to block: number={}. transaction_hash={:?}, Error: {:?}",
|
||||||
|
block_number, hash, e);
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// And close
|
// And close
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
trace!("Sealing: number={}, hash={}, diff={}",
|
trace!(target: "miner", "Sealing: number={}, hash={}, diff={}",
|
||||||
b.block().header().number(),
|
b.block().header().number(),
|
||||||
b.hash(),
|
b.hash(),
|
||||||
b.block().header().difficulty()
|
b.block().header().difficulty()
|
||||||
);
|
);
|
||||||
Some(b)
|
Some((b, invalid_transactions))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
@ -26,6 +26,7 @@ pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};
|
|||||||
pub use self::ids::{BlockId, TransactionId};
|
pub use self::ids::{BlockId, TransactionId};
|
||||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
use util::bytes::Bytes;
|
use util::bytes::Bytes;
|
||||||
use util::hash::{Address, H256, H2048};
|
use util::hash::{Address, H256, H2048};
|
||||||
use util::numbers::U256;
|
use util::numbers::U256;
|
||||||
@ -110,7 +111,8 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
|
|
||||||
// TODO [todr] Should be moved to miner crate eventually.
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
/// Returns ClosedBlock prepared for sealing.
|
/// Returns ClosedBlock prepared for sealing.
|
||||||
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>) -> Option<ClosedBlock>;
|
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
|
||||||
|
-> Option<(ClosedBlock, HashSet<H256>)>;
|
||||||
|
|
||||||
// TODO [todr] Should be moved to miner crate eventually.
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
/// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error.
|
/// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error.
|
||||||
|
@ -217,7 +217,7 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<ClosedBlock> {
|
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<(ClosedBlock, HashSet<H256>)> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ fn can_mine() {
|
|||||||
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
|
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
|
|
||||||
let b = client.prepare_sealing(Address::default(), x!(31415926), vec![], vec![]).unwrap();
|
let b = client.prepare_sealing(Address::default(), x!(31415926), vec![], vec![]).unwrap().0;
|
||||||
|
|
||||||
assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
|
assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
|
||||||
assert!(client.try_seal(b, vec![]).is_ok());
|
assert!(client.try_seal(b, vec![]).is_ok());
|
||||||
|
@ -132,7 +132,18 @@ impl MinerService for Miner {
|
|||||||
self.extra_data(),
|
self.extra_data(),
|
||||||
transactions,
|
transactions,
|
||||||
);
|
);
|
||||||
*self.sealing_block.lock().unwrap() = b;
|
|
||||||
|
*self.sealing_block.lock().unwrap() = b.map(|(block, invalid_transactions)| {
|
||||||
|
let mut queue = self.transaction_queue.lock().unwrap();
|
||||||
|
queue.remove_all(
|
||||||
|
&invalid_transactions.into_iter().collect::<Vec<H256>>(),
|
||||||
|
|a: &Address| AccountDetails {
|
||||||
|
nonce: chain.nonce(a),
|
||||||
|
balance: chain.balance(a),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
block
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> {
|
fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user