Skip to content

Commit

Permalink
Merge pull request #2358 from AleoHQ/feat/timestamp-committee
Browse files Browse the repository at this point in the history
[ZKS-02] Use committee lookback at `anchor_round - 1` for timestamp calculation
  • Loading branch information
howardwu authored Feb 16, 2024
2 parents b396a51 + 870cd70 commit bb54fc4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
11 changes: 9 additions & 2 deletions ledger/block/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl<N: Network> Block<N> {
&self,
previous_block: &Block<N>,
current_state_root: N::StateRoot,
previous_committee_lookback: &Committee<N>,
current_committee_lookback: &Committee<N>,
current_puzzle: &CoinbasePuzzle<N>,
current_epoch_challenge: &EpochChallenge<N>,
Expand All @@ -46,7 +47,12 @@ impl<N: Network> Block<N> {
expected_timestamp,
expected_existing_solution_ids,
expected_existing_transaction_ids,
) = self.verify_authority(previous_block.round(), previous_block.height(), current_committee_lookback)?;
) = self.verify_authority(
previous_block.round(),
previous_block.height(),
previous_committee_lookback,
current_committee_lookback,
)?;

// Ensure the block solutions are correct.
let (
Expand Down Expand Up @@ -143,6 +149,7 @@ impl<N: Network> Block<N> {
&self,
previous_round: u64,
previous_height: u32,
previous_committee_lookback: &Committee<N>,
current_committee_lookback: &Committee<N>,
) -> Result<(u64, u32, i64, Vec<PuzzleCommitment<N>>, Vec<N::TransactionID>)> {
// Note: Do not remove this. This ensures that all blocks after genesis are quorum blocks.
Expand Down Expand Up @@ -223,7 +230,7 @@ impl<N: Network> Block<N> {
// Beacon blocks do not have a timestamp check.
Authority::Beacon(..) => self.timestamp(),
// Quorum blocks use the weighted median timestamp from the subdag.
Authority::Quorum(subdag) => subdag.timestamp(current_committee_lookback),
Authority::Quorum(subdag) => subdag.timestamp(previous_committee_lookback),
};

// Return success.
Expand Down
26 changes: 18 additions & 8 deletions ledger/src/advance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,25 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
// Determine the timestamp for the next block.
let next_timestamp = match subdag {
Some(subdag) => {
// Get the committee lookback round.
let committee_lookback_round =
subdag.anchor_round().saturating_sub(Committee::<N>::COMMITTEE_LOOKBACK_RANGE);
// Retrieve the committee lookback.
let committee_lookback = self
.get_committee_for_round(committee_lookback_round)?
.ok_or(anyhow!("Failed to fetch committee for round {committee_lookback_round}"))?;
// Retrieve the previous committee lookback.
let previous_committee_lookback = {
// Calculate the penultimate round, which is the round before the anchor round.
let penultimate_round = subdag.anchor_round().saturating_sub(1);
// Get the round number for the previous committee. Note, we subtract 2 from odd rounds,
// because committees are updated in even rounds.
let previous_penultimate_round = match penultimate_round % 2 == 0 {
true => penultimate_round.saturating_sub(1),
false => penultimate_round.saturating_sub(2),
};
// Get the previous committee lookback round.
let penultimate_committee_lookback_round =
previous_penultimate_round.saturating_sub(Committee::<N>::COMMITTEE_LOOKBACK_RANGE);
// Output the previous committee lookback.
self.get_committee_for_round(penultimate_committee_lookback_round)?
.ok_or(anyhow!("Failed to fetch committee for round {penultimate_committee_lookback_round}"))?
};
// Return the timestamp for the given committee lookback.
subdag.timestamp(&committee_lookback)
subdag.timestamp(&previous_committee_lookback)
}
None => OffsetDateTime::now_utc().unix_timestamp(),
};
Expand Down
43 changes: 32 additions & 11 deletions ledger/src/check_next_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,44 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
let ratified_finalize_operations =
self.vm.check_speculate(state, block.ratifications(), block.solutions(), block.transactions())?;

// Get the round number for the previous committee. Note, we subtract 2 from odd rounds,
// because committees are updated in even rounds.
let previous_round = match block.round() % 2 == 0 {
true => block.round().saturating_sub(1),
false => block.round().saturating_sub(2),
};
// Get the committee lookback round.
let committee_lookback_round = previous_round.saturating_sub(Committee::<N>::COMMITTEE_LOOKBACK_RANGE);
// Retrieve the committee lookback.
let committee_lookback = self
.get_committee_for_round(committee_lookback_round)?
.ok_or(anyhow!("Failed to fetch committee for round {committee_lookback_round}"))?;
let committee_lookback = {
// Determine the round number for the previous committee. Note, we subtract 2 from odd rounds,
// because committees are updated in even rounds.
let previous_round = match block.round() % 2 == 0 {
true => block.round().saturating_sub(1),
false => block.round().saturating_sub(2),
};
// Determine the committee lookback round.
let committee_lookback_round = previous_round.saturating_sub(Committee::<N>::COMMITTEE_LOOKBACK_RANGE);
// Output the committee lookback.
self.get_committee_for_round(committee_lookback_round)?
.ok_or(anyhow!("Failed to fetch committee for round {committee_lookback_round}"))?
};

// Retrieve the previous committee lookback.
let previous_committee_lookback = {
// Calculate the penultimate round, which is the round before the anchor round.
let penultimate_round = block.round().saturating_sub(1);
// Determine the round number for the previous committee. Note, we subtract 2 from odd rounds,
// because committees are updated in even rounds.
let previous_penultimate_round = match penultimate_round % 2 == 0 {
true => penultimate_round.saturating_sub(1),
false => penultimate_round.saturating_sub(2),
};
// Determine the previous committee lookback round.
let penultimate_committee_lookback_round =
previous_penultimate_round.saturating_sub(Committee::<N>::COMMITTEE_LOOKBACK_RANGE);
// Output the previous committee lookback.
self.get_committee_for_round(penultimate_committee_lookback_round)?
.ok_or(anyhow!("Failed to fetch committee for round {penultimate_committee_lookback_round}"))?
};

// Ensure the block is correct.
let (expected_existing_solution_ids, expected_existing_transaction_ids) = block.verify(
&self.latest_block(),
self.latest_state_root(),
&previous_committee_lookback,
&committee_lookback,
self.coinbase_puzzle(),
&self.latest_epoch_challenge()?,
Expand Down

0 comments on commit bb54fc4

Please sign in to comment.