Removing invalid transactions from queue
This commit is contained in:
parent
22bc9f6458
commit
c382fa7eab
@ -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,41 @@ 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 gas_limit = *b.block().header().gas_limit();
|
||||||
|
let mut gas_left = gas_limit;
|
||||||
|
let mut invalid_transactions = HashSet::new();
|
||||||
|
|
||||||
for tx in transactions {
|
for tx in transactions {
|
||||||
|
let hash = tx.hash();
|
||||||
|
let gas = tx.gas;
|
||||||
|
// TODO [todr] It seems that calculating gas_left here doesn't really look nice. After moving this function
|
||||||
|
// to miner crate we should consider rewriting this logic in some better way.
|
||||||
|
if gas > gas_left {
|
||||||
|
trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", hash);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let import = b.push_transaction(tx, None);
|
let import = b.push_transaction(tx, None);
|
||||||
if let Err(e) = import {
|
match import {
|
||||||
trace!("Error adding transaction to block: number={}. Error: {:?}", block_number, e);
|
Err(e) => {
|
||||||
|
trace!(target: "miner", "Error adding transaction to block: number={}. transaction_hash={:?}, Error: {:?}",
|
||||||
|
block_number, hash, e);
|
||||||
|
invalid_transactions.insert(hash);
|
||||||
|
},
|
||||||
|
Ok(receipt) => {
|
||||||
|
gas_left = gas_limit - receipt.gas_used;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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,20 @@ impl MinerService for Miner {
|
|||||||
self.extra_data(),
|
self.extra_data(),
|
||||||
transactions,
|
transactions,
|
||||||
);
|
);
|
||||||
*self.sealing_block.lock().unwrap() = b;
|
|
||||||
|
match b {
|
||||||
|
None => {
|
||||||
|
*self.sealing_block.lock().unwrap() = None
|
||||||
|
},
|
||||||
|
Some((block, invalid_transactions)) => {
|
||||||
|
let mut queue = self.transaction_queue.lock().unwrap();
|
||||||
|
queue.remove_all(
|
||||||
|
&invalid_transactions.into_iter().collect::<Vec<H256>>(),
|
||||||
|
|a: &Address| chain.nonce(a)
|
||||||
|
);
|
||||||
|
*self.sealing_block.lock().unwrap() = Some(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