Fallback to building empty block to mine (if txpool is somehow in invalid state) (#2451)

* log loudly if we fail to prepare txs for mining
This commit is contained in:
Ignotus Peverell 2019-01-23 10:31:49 -08:00 committed by GitHub
commit 2299a03248
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -107,8 +107,21 @@ fn build_block(
// Note: do not keep the difficulty_iter in scope (it has an active batch). // Note: do not keep the difficulty_iter in scope (it has an active batch).
let difficulty = consensus::next_difficulty(head.height + 1, chain.difficulty_iter()); let difficulty = consensus::next_difficulty(head.height + 1, chain.difficulty_iter());
// extract current transaction from the pool // Extract current "mineable" transactions from the pool.
let txs = tx_pool.read().prepare_mineable_transactions()?; // If this fails for *any* reason then fallback to an empty vec of txs.
// This will allow us to mine an "empty" block if the txpool is in an
// invalid (and unexpected) state.
let txs = match tx_pool.read().prepare_mineable_transactions() {
Ok(txs) => txs,
Err(e) => {
error!(
"build_block: Failed to prepare mineable txs from txpool: {:?}",
e
);
warn!("build_block: Falling back to mining empty block.");
vec![]
}
};
// build the coinbase and the block itself // build the coinbase and the block itself
let fees = txs.iter().map(|tx| tx.fee()).sum(); let fees = txs.iter().map(|tx| tx.fee()).sum();
@ -138,21 +151,18 @@ fn build_block(
); );
// Now set txhashset roots and sizes on the header of the block being built. // Now set txhashset roots and sizes on the header of the block being built.
let roots_result = chain.set_txhashset_roots(&mut b); match chain.set_txhashset_roots(&mut b) {
match roots_result {
Ok(_) => Ok((b, block_fees)), Ok(_) => Ok((b, block_fees)),
// If it's a duplicate commitment, it's likely trying to use
// a key that's already been derived but not in the wallet
// for some reason, allow caller to retry
Err(e) => { Err(e) => {
match e.kind() { match e.kind() {
// If this is a duplicate commitment then likely trying to use
// a key that hass already been derived but not in the wallet
// for some reason, allow caller to retry.
chain::ErrorKind::DuplicateCommitment(e) => Err(Error::Chain( chain::ErrorKind::DuplicateCommitment(e) => Err(Error::Chain(
chain::ErrorKind::DuplicateCommitment(e).into(), chain::ErrorKind::DuplicateCommitment(e).into(),
)), )),
//Some other issue, possibly duplicate kernel // Some other issue, possibly duplicate kernel
_ => { _ => {
error!("Error setting txhashset root to build a block: {:?}", e); error!("Error setting txhashset root to build a block: {:?}", e);
Err(Error::Chain( Err(Error::Chain(