-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Update sealing just once when externally importing many blocks #1541
Changes from all commits
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 |
---|---|---|
|
@@ -315,6 +315,19 @@ impl Miner { | |
!have_work | ||
} | ||
|
||
fn add_transactions_to_queue(&self, chain: &MiningBlockChainClient, transactions: Vec<SignedTransaction>, origin: TransactionOrigin, transaction_queue: &mut TransactionQueue) -> | ||
Vec<Result<TransactionImportResult, Error>> { | ||
|
||
let fetch_account = |a: &Address| AccountDetails { | ||
nonce: chain.latest_nonce(a), | ||
balance: chain.latest_balance(a), | ||
}; | ||
|
||
transactions.into_iter() | ||
.map(|tx| transaction_queue.add(tx, &fetch_account, origin)) | ||
.collect() | ||
} | ||
|
||
/// Are we allowed to do a non-mandatory reseal? | ||
fn tx_reseal_allowed(&self) -> bool { Instant::now() > *self.next_allowed_reseal.lock().unwrap() } | ||
} | ||
|
@@ -478,35 +491,32 @@ impl MinerService for Miner { | |
self.gas_range_target.read().unwrap().1 | ||
} | ||
|
||
fn import_transactions<T>(&self, chain: &MiningBlockChainClient, transactions: Vec<SignedTransaction>, fetch_account: T) -> | ||
Vec<Result<TransactionImportResult, Error>> | ||
where T: Fn(&Address) -> AccountDetails { | ||
let results: Vec<Result<TransactionImportResult, Error>> = { | ||
let mut transaction_queue = self.transaction_queue.lock().unwrap(); | ||
transactions.into_iter() | ||
.map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External)) | ||
.collect() | ||
}; | ||
if !results.is_empty() && self.options.reseal_on_external_tx && self.tx_reseal_allowed() { | ||
fn import_external_transactions(&self, chain: &MiningBlockChainClient, transactions: Vec<SignedTransaction>) -> | ||
Vec<Result<TransactionImportResult, Error>> { | ||
|
||
let mut transaction_queue = self.transaction_queue.lock().unwrap(); | ||
let results = self.add_transactions_to_queue(chain, transactions, TransactionOrigin::External, | ||
&mut transaction_queue); | ||
|
||
if !results.is_empty() && self.options.reseal_on_external_tx && self.tx_reseal_allowed() { | ||
self.update_sealing(chain); | ||
} | ||
results | ||
} | ||
|
||
fn import_own_transaction<T>( | ||
fn import_own_transaction( | ||
&self, | ||
chain: &MiningBlockChainClient, | ||
transaction: SignedTransaction, | ||
fetch_account: T | ||
) -> Result<TransactionImportResult, Error> where T: Fn(&Address) -> AccountDetails { | ||
) -> Result<TransactionImportResult, Error> { | ||
|
||
let hash = transaction.hash(); | ||
trace!(target: "own_tx", "Importing transaction: {:?}", transaction); | ||
|
||
let imported = { | ||
// Be sure to release the lock before we call enable_and_prepare_sealing | ||
let mut transaction_queue = self.transaction_queue.lock().unwrap(); | ||
let import = transaction_queue.add(transaction, &fetch_account, TransactionOrigin::Local); | ||
let import = self.add_transactions_to_queue(chain, vec![transaction], TransactionOrigin::Local, &mut transaction_queue).pop().unwrap(); | ||
|
||
match import { | ||
Ok(ref res) => { | ||
|
@@ -657,7 +667,12 @@ impl MinerService for Miner { | |
// Client should send message after commit to db and inserting to chain. | ||
.expect("Expected in-chain blocks."); | ||
let block = BlockView::new(&block); | ||
block.transactions() | ||
let txs = block.transactions(); | ||
// populate sender | ||
for tx in &txs { | ||
let _sender = tx.sender(); | ||
} | ||
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. I'm not sure what the value of populating the sender explicitly here rather than letting it occur lazily as it's needed. What's the purpose of this complexity here? I'd vote just dumping these 3 lines if that's ok. The only benefit I can think of is to populate it on this thread for performance reasons, but are they really that critical? 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. Populating 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. Ah. I moved the logic up to "fetch_transactions" so it happens in both of the below loops. Otherwise, still happening outside the lock in parallel. Doubtful it makes too big of a difference, but I don't have data, so leave it to be safe. |
||
txs | ||
} | ||
|
||
// 1. We ignore blocks that were `imported` (because it means that they are not in canon-chain, and transactions | ||
|
@@ -674,14 +689,9 @@ impl MinerService for Miner { | |
.par_iter() | ||
.map(|h| fetch_transactions(chain, h)); | ||
out_of_chain.for_each(|txs| { | ||
// populate sender | ||
for tx in &txs { | ||
let _sender = tx.sender(); | ||
} | ||
let _ = self.import_transactions(chain, txs, |a| AccountDetails { | ||
nonce: chain.latest_nonce(a), | ||
balance: chain.latest_balance(a), | ||
}); | ||
let mut transaction_queue = self.transaction_queue.lock().unwrap(); | ||
let _ = self.add_transactions_to_queue(chain, txs, TransactionOrigin::External, | ||
&mut transaction_queue); | ||
}); | ||
} | ||
|
||
|
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.
We use a bit different indentation style. I think I would write something like this here:
Or would just keep it single line.
(Same in L693)