Use next available key on duplicate coinbase commitment (#2737)

If a coinbase commitment hits a duplication and there is no transactions
to mine, it is possible that coinbase cannot be built for quite a long
time. This change tries to build coinbase with an empty key identifier
immediately in this case. The listening wallet will then use the next
available key to build a coinbase commitment, which is different from
the previous one and is unlikely to hit the duplication.
This commit is contained in:
Hanjiang Yu 2019-04-16 06:16:33 +08:00 committed by Ignotus Peverell
parent 606b4652f8
commit 56fed5093e

View file

@ -51,12 +51,15 @@ pub fn get_block(
wallet_listener_url.clone(), wallet_listener_url.clone(),
); );
while let Err(e) = result { while let Err(e) = result {
let mut new_key_id = key_id.to_owned();
match e { match e {
self::Error::Chain(c) => match c.kind() { self::Error::Chain(c) => match c.kind() {
chain::ErrorKind::DuplicateCommitment(_) => { chain::ErrorKind::DuplicateCommitment(_) => {
debug!( debug!(
"Duplicate commit for potential coinbase detected. Trying next derivation." "Duplicate commit for potential coinbase detected. Trying next derivation."
); );
// use the next available key to generate a different coinbase commitment
new_key_id = None;
} }
_ => { _ => {
error!("Chain Error: {}", c); error!("Chain Error: {}", c);
@ -73,12 +76,18 @@ pub fn get_block(
warn!("Error building new block: {:?}. Retrying.", ae); warn!("Error building new block: {:?}. Retrying.", ae);
} }
} }
// only wait if we are still using the same key: a different coinbase commitment is unlikely
// to have duplication
if new_key_id.is_some() {
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));
}
result = build_block( result = build_block(
chain, chain,
tx_pool, tx_pool,
verifier_cache.clone(), verifier_cache.clone(),
key_id.clone(), new_key_id,
wallet_listener_url.clone(), wallet_listener_url.clone(),
); );
} }