in consensus/src/lib.rs [261:301]
fn order_dag(&self, leader: &Certificate, state: &State) -> Vec<Certificate> {
debug!("Processing sub-dag of {:?}", leader);
let mut ordered = Vec::new();
let mut already_ordered = HashSet::new();
let mut buffer = vec![leader];
while let Some(x) = buffer.pop() {
debug!("Sequencing {:?}", x);
ordered.push(x.clone());
for parent in &x.header.parents {
let (digest, certificate) = match state
.dag
.get(&(x.round() - 1))
.map(|x| x.values().find(|(x, _)| x == parent))
.flatten()
{
Some(x) => x,
None => continue, // We already ordered or GC up to here.
};
// We skip the certificate if we (1) already processed it or (2) we reached a round that we already
// committed for this authority.
let mut skip = already_ordered.contains(&digest);
skip |= state
.last_committed
.get(&certificate.origin())
.map_or_else(|| false, |r| r == &certificate.round());
if !skip {
buffer.push(certificate);
already_ordered.insert(digest);
}
}
}
// Ensure we do not commit garbage collected certificates.
ordered.retain(|x| x.round() + self.gc_depth >= state.last_committed_round);
// Ordering the output by round is not really necessary but it makes the commit sequence prettier.
ordered.sort_by_key(|x| x.round());
ordered
}