mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
infinite loops in check_orphans, if block in orphans has a forked parent (#1452)
* fix: if block in orphans queue has a forked parent, cause infinite loop in check_orphans() * process all orphans at a given height before go to next height
This commit is contained in:
parent
8a39f1fc75
commit
f971e8de77
1 changed files with 40 additions and 22 deletions
|
@ -350,41 +350,59 @@ impl Chain {
|
||||||
|
|
||||||
/// Check for orphans, once a block is successfully added
|
/// Check for orphans, once a block is successfully added
|
||||||
pub fn check_orphans(&self, mut height: u64) {
|
pub fn check_orphans(&self, mut height: u64) {
|
||||||
trace!(
|
let initial_height = height;
|
||||||
LOGGER,
|
|
||||||
"chain: doing check_orphans at {}, # orphans {}",
|
|
||||||
height,
|
|
||||||
self.orphans.len(),
|
|
||||||
);
|
|
||||||
// Is there an orphan in our orphans that we can now process?
|
// Is there an orphan in our orphans that we can now process?
|
||||||
loop {
|
loop {
|
||||||
|
trace!(
|
||||||
|
LOGGER,
|
||||||
|
"check_orphans: at {}, # orphans {}",
|
||||||
|
height,
|
||||||
|
self.orphans.len(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut orphan_accepted = false;
|
||||||
|
let mut height_accepted = height;
|
||||||
|
|
||||||
if let Some(orphans) = self.orphans.remove_by_height(&height) {
|
if let Some(orphans) = self.orphans.remove_by_height(&height) {
|
||||||
for orphan in orphans {
|
let orphans_len = orphans.len();
|
||||||
trace!(
|
for (i, orphan) in orphans.into_iter().enumerate() {
|
||||||
|
debug!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"chain: got block {} at {} from orphans. # orphans remaining {}",
|
"check_orphans: get block {} at {}{}",
|
||||||
orphan.block.hash(),
|
orphan.block.hash(),
|
||||||
height,
|
height,
|
||||||
self.orphans.len(),
|
if orphans_len > 1 {
|
||||||
|
format!(", no.{} of {} orphans", i, orphans_len)
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
},
|
||||||
);
|
);
|
||||||
let res = self.process_block_no_orphans(orphan.block, orphan.opts);
|
let res = self.process_block_no_orphans(orphan.block, orphan.opts);
|
||||||
if let Ok((_, Some(b))) = res {
|
if let Ok((_, Some(b))) = res {
|
||||||
// We accepted a block, so see if we can accept any orphans
|
orphan_accepted = true;
|
||||||
height = b.header.height + 1;
|
height_accepted = b.header.height;
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
break;
|
if orphan_accepted {
|
||||||
|
// We accepted a block, so see if we can accept any orphans
|
||||||
|
height = height_accepted + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if initial_height != height {
|
||||||
|
debug!(
|
||||||
|
LOGGER,
|
||||||
|
"check_orphans: {} blocks accepted since height {}, remaining # orphans {}",
|
||||||
|
height - initial_height,
|
||||||
|
initial_height,
|
||||||
|
self.orphans.len(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
trace!(
|
|
||||||
LOGGER,
|
|
||||||
"chain: done check_orphans at {}. # remaining orphans {}",
|
|
||||||
height - 1,
|
|
||||||
self.orphans.len(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For the given commitment find the unspent output and return the
|
/// For the given commitment find the unspent output and return the
|
||||||
|
|
Loading…
Reference in a new issue