in librabft-v2/src/record_store.rs [456:541]
fn try_insert_network_record(
&mut self,
record: Record<Context>,
context: &mut Context,
) -> Result<()> {
// First, check that the record is "relevant" and that invariants of "verified records",
// such as chaining, are respected.
let hash = self.verify_network_record(&*context, &record)?;
// Second, insert the record. In the case of QC, this is where check execution states.
match record {
Record::Block(block) => {
let block_hash = BlockHash(hash);
if block.value.round == self.current_round
&& PacemakerState::leader(&*self, block.value.round) == block.value.author
{
// If we use a VRF, this assumes that we have inserted the highest commit rule
// beforehand.
self.current_proposed_block = Some(block_hash);
}
self.blocks.insert(block_hash, block);
}
Record::Vote(vote) => {
self.current_votes.insert(vote.value.author, vote.clone());
let has_newly_won_election = match &mut self.current_election {
ElectionState::Ongoing { ballot } => {
let entry = ballot
.entry((vote.value.certified_block_hash, vote.value.state.clone()))
.or_insert(0);
*entry += self.configuration.weight(&vote.value.author);
if *entry >= self.configuration.quorum_threshold() {
Some(ElectionState::Won {
block_hash: vote.value.certified_block_hash,
state: vote.value.state,
})
} else {
None
}
}
_ => None,
};
if let Some(won_election) = has_newly_won_election {
self.current_election = won_election;
}
}
Record::QuorumCertificate(qc) => {
let block_hash = qc.value.certified_block_hash;
let qc_hash = QuorumCertificateHash(hash);
let qc_round = qc.value.round;
let qc_state = qc.value.state.clone();
self.quorum_certificates.insert(qc_hash, qc);
// Make sure that the state in the QC is known to execution.
match self.compute_state(block_hash, context) {
Some(state) => {
ensure!(
state == qc_state,
"I computed a different state for a QC. This is very bad: {:?}",
qc_state
);
}
None => {
bail!("I failed to execute a block with a QC at {:?} while my last commit is at {:?}", qc_round, self.highest_committed_round);
}
}
// Update computed values.
if qc_round > self.highest_quorum_certificate_round {
self.highest_quorum_certificate_round = qc_round;
self.highest_quorum_certificate_hash = qc_hash;
}
self.update_current_round(qc_round + 1);
self.update_commit_3chain_round(qc_hash);
}
Record::Timeout(timeout) => {
self.current_timeouts
.insert(timeout.value.author, timeout.clone());
self.current_timeouts_weight += self.configuration.weight(&timeout.value.author);
if self.current_timeouts_weight >= self.configuration.quorum_threshold() {
let timeout_certificate =
self.current_timeouts.iter().map(|x| x.1.clone()).collect();
self.highest_timeout_certificate = Some(timeout_certificate);
self.highest_timeout_certificate_round = self.current_round;
self.update_current_round(self.current_round + 1);
}
}
}
Ok(())
}