-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Removing transactions that failed to be pushed to block. #752
Changes from 2 commits
c382fa7
c4021a7
fece330
48c72a1
a6bd15d
7d77324
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -391,7 +391,8 @@ impl<V> BlockChainClient for Client<V> where V: Verifier { | |
} | ||
|
||
// 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 h = self.chain.best_block_hash(); | ||
|
||
|
@@ -417,21 +418,48 @@ impl<V> BlockChainClient for Client<V> where V: Verifier { | |
|
||
// Add transactions | ||
let block_number = b.block().header().number(); | ||
let min_tx_gas = U256::from(self.engine.schedule(&b.env_info()).tx_gas); | ||
let gas_limit = *b.block().header().gas_limit(); | ||
let mut gas_left = gas_limit; | ||
let mut invalid_transactions = HashSet::new(); | ||
|
||
for tx in transactions { | ||
// Stop early if we are sure that no other transaction will be included | ||
if gas_left < min_tx_gas { | ||
break; | ||
} | ||
|
||
// TODO [todr] It seems that calculating gas_left here doesn't look nice. After moving this function | ||
// to miner crate we should consider rewriting this logic in some better way. | ||
if tx.gas > gas_left { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any reason to duplicate this check here rather than just checking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, I guess it would be possible to unwrap error, check if it's Will refactor, because calculating gas here is not particularly appealing. |
||
trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", tx.hash()); | ||
continue; | ||
} | ||
|
||
// Push transaction to block | ||
let hash = tx.hash(); | ||
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(e) => { | ||
invalid_transactions.insert(hash); | ||
trace!(target: "miner", | ||
"Error adding transaction to block: number={}. transaction_hash={:?}, Error: {:?}", | ||
block_number, hash, e); | ||
}, | ||
Ok(receipt) => { | ||
gas_left = gas_limit - receipt.gas_used; | ||
} | ||
} | ||
} | ||
|
||
// And close | ||
let b = b.close(); | ||
trace!("Sealing: number={}, hash={}, diff={}", | ||
trace!(target: "miner", "Sealing: number={}, hash={}, diff={}", | ||
b.block().header().number(), | ||
b.hash(), | ||
b.block().header().difficulty() | ||
); | ||
Some(b) | ||
Some((b, invalid_transactions)) | ||
} | ||
|
||
fn block_header(&self, id: BlockId) -> Option<Bytes> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,7 +132,20 @@ impl MinerService for Miner { | |
self.extra_data(), | ||
transactions, | ||
); | ||
*self.sealing_block.lock().unwrap() = b; | ||
|
||
match b { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could be done more succinctly as:
no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True - in this case it looks much better. However in general I'm trying to avoid side effects in |
||
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>> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stop when gas_left < min transaction gas (21000). There should be a constant for it in the Schedule I believe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.