|
@@ -588,11 +588,10 @@ impl ValidatorState {
|
|
|
|
|
|
|
|
/// Node checks if any of the fork chains can be finalized.
|
|
/// Node checks if any of the fork chains can be finalized.
|
|
|
/// Consensus finalization logic:
|
|
/// Consensus finalization logic:
|
|
|
- /// - If the node has observed the creation of 3 proposals in a fork chain and no other
|
|
|
|
|
- /// forks exists at same or greater height, it finalizes (appends to canonical blockchain)
|
|
|
|
|
- /// all proposals up to the last one.
|
|
|
|
|
|
|
+ /// - If the node has observed the creation of a fork chain and no other forks exists at same or greater height,
|
|
|
|
|
+ /// it finalizes (appends to canonical blockchain) all proposals in that fork chain.
|
|
|
/// When fork chain proposals are finalized, the rest of fork chains are removed and all
|
|
/// When fork chain proposals are finalized, the rest of fork chains are removed and all
|
|
|
- /// slot checkpoints until current slot are apppended to canonical state.
|
|
|
|
|
|
|
+ /// slot checkpoints are apppended to canonical state.
|
|
|
pub async fn chain_finalization(&mut self) -> Result<(Vec<BlockInfo>, Vec<SlotCheckpoint>)> {
|
|
pub async fn chain_finalization(&mut self) -> Result<(Vec<BlockInfo>, Vec<SlotCheckpoint>)> {
|
|
|
let slot = self.consensus.current_slot();
|
|
let slot = self.consensus.current_slot();
|
|
|
info!(target: "consensus::validator", "chain_finalization(): Started finalization check for slot: {}", slot);
|
|
info!(target: "consensus::validator", "chain_finalization(): Started finalization check for slot: {}", slot);
|
|
@@ -600,7 +599,7 @@ impl ValidatorState {
|
|
|
self.consensus.checked_finalization = slot;
|
|
self.consensus.checked_finalization = slot;
|
|
|
|
|
|
|
|
// First we find longest fork without any other forks at same height
|
|
// First we find longest fork without any other forks at same height
|
|
|
- let mut fork_index = 0;
|
|
|
|
|
|
|
+ let mut fork_index = -1;
|
|
|
// Use this index to extract leaders count sequence from longest fork
|
|
// Use this index to extract leaders count sequence from longest fork
|
|
|
let mut index_for_history = -1;
|
|
let mut index_for_history = -1;
|
|
|
let mut max_length_for_history = 0;
|
|
let mut max_length_for_history = 0;
|
|
@@ -635,32 +634,27 @@ impl ValidatorState {
|
|
|
self.consensus.set_leader_history(index_for_history, slot);
|
|
self.consensus.set_leader_history(index_for_history, slot);
|
|
|
return Ok((vec![], vec![]))
|
|
return Ok((vec![], vec![]))
|
|
|
}
|
|
}
|
|
|
|
|
+ -1 => {
|
|
|
|
|
+ info!(target: "consensus::validator", "chain_finalization(): Nothing to finalize.");
|
|
|
|
|
+ }
|
|
|
_ => {
|
|
_ => {
|
|
|
info!(target: "consensus::validator", "chain_finalization(): Chain {} can be finalized!", fork_index)
|
|
info!(target: "consensus::validator", "chain_finalization(): Chain {} can be finalized!", fork_index)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if max_length == 0 {
|
|
|
|
|
- return Ok((vec![], vec![]))
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
if max_length == 0 {
|
|
if max_length == 0 {
|
|
|
return Ok((vec![], vec![]))
|
|
return Ok((vec![], vec![]))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Starting finalization
|
|
// Starting finalization
|
|
|
- let mut fork = self.consensus.forks[fork_index as usize].clone();
|
|
|
|
|
|
|
+ let fork = self.consensus.forks[fork_index as usize].clone();
|
|
|
|
|
|
|
|
// Retrieving proposals to finalize
|
|
// Retrieving proposals to finalize
|
|
|
- let bound = max_length - 1;
|
|
|
|
|
let mut finalized: Vec<BlockInfo> = vec![];
|
|
let mut finalized: Vec<BlockInfo> = vec![];
|
|
|
- let mut last_state_checkpoint = fork.sequence.first().unwrap().clone();
|
|
|
|
|
- for state_checkpoint in &fork.sequence[..bound] {
|
|
|
|
|
|
|
+ for state_checkpoint in &fork.sequence {
|
|
|
finalized.push(state_checkpoint.proposal.clone().into());
|
|
finalized.push(state_checkpoint.proposal.clone().into());
|
|
|
- last_state_checkpoint = state_checkpoint.clone();
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Removing finalized proposals state checkpoins from fork
|
|
|
|
|
- fork.sequence.drain(..bound);
|
|
|
|
|
-
|
|
|
|
|
// Adding finalized proposals to canonical
|
|
// Adding finalized proposals to canonical
|
|
|
info!(target: "consensus::validator", "consensus: Adding {} finalized block to canonical chain.", finalized.len());
|
|
info!(target: "consensus::validator", "consensus: Adding {} finalized block to canonical chain.", finalized.len());
|
|
|
match self.blockchain.add(&finalized) {
|
|
match self.blockchain.add(&finalized) {
|
|
@@ -699,12 +693,9 @@ impl ValidatorState {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Setting leaders history to last proposal leaders count
|
|
// Setting leaders history to last proposal leaders count
|
|
|
|
|
+ let last_state_checkpoint = fork.sequence.last().unwrap().clone();
|
|
|
self.consensus.leaders_history =
|
|
self.consensus.leaders_history =
|
|
|
- vec![fork.sequence.last().unwrap().proposal.block.lead_info.leaders];
|
|
|
|
|
-
|
|
|
|
|
- // Removing rest forks
|
|
|
|
|
- self.consensus.forks = vec![];
|
|
|
|
|
- self.consensus.forks.push(fork);
|
|
|
|
|
|
|
+ vec![last_state_checkpoint.proposal.block.lead_info.leaders];
|
|
|
|
|
|
|
|
// Setting canonical states from last finalized checkpoint
|
|
// Setting canonical states from last finalized checkpoint
|
|
|
self.consensus.coins = last_state_checkpoint.coins;
|
|
self.consensus.coins = last_state_checkpoint.coins;
|
|
@@ -712,18 +703,8 @@ impl ValidatorState {
|
|
|
self.consensus.nullifiers = last_state_checkpoint.nullifiers;
|
|
self.consensus.nullifiers = last_state_checkpoint.nullifiers;
|
|
|
|
|
|
|
|
// Adding finalized slot checkpoints to canonical
|
|
// Adding finalized slot checkpoints to canonical
|
|
|
- let mut bound = 0;
|
|
|
|
|
- let mut finalized_slot_checkpoints: Vec<SlotCheckpoint> = vec![];
|
|
|
|
|
- for (index, slot_checkpoint) in self.consensus.slot_checkpoints.iter().enumerate() {
|
|
|
|
|
- if slot_checkpoint.slot >= slot {
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
- bound = index;
|
|
|
|
|
- finalized_slot_checkpoints.push(slot_checkpoint.clone());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Removing finalized proposals from chain
|
|
|
|
|
- self.consensus.slot_checkpoints.drain(..bound);
|
|
|
|
|
|
|
+ let finalized_slot_checkpoints: Vec<SlotCheckpoint> =
|
|
|
|
|
+ self.consensus.slot_checkpoints.clone();
|
|
|
|
|
|
|
|
debug!(
|
|
debug!(
|
|
|
target: "consensus::validator",
|
|
target: "consensus::validator",
|
|
@@ -742,6 +723,10 @@ impl ValidatorState {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // Resetting forks and slot checkpoints
|
|
|
|
|
+ self.consensus.forks = vec![];
|
|
|
|
|
+ self.consensus.slot_checkpoints = vec![];
|
|
|
|
|
+
|
|
|
Ok((finalized, finalized_slot_checkpoints))
|
|
Ok((finalized, finalized_slot_checkpoints))
|
|
|
}
|
|
}
|
|
|
|
|
|