1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0
use crate::liveness::proposer_election::ProposerElection;
use consensus_types::common::{Author, Round};
/// The rotating proposer maps a round to an author according to a round-robin rotation.
/// A fixed proposer strategy loses liveness when the fixed proposer is down. Rotating proposers
/// won't gather quorum certificates to machine loss/byzantine behavior on f/n rounds.
pub struct RotatingProposer {
// Ordering of proposers to rotate through (all honest replicas must agree on this)
proposers: Vec<Author>,
// Number of contiguous rounds (i.e. round numbers increase by 1) a proposer is active
// in a row
contiguous_rounds: u32,
}
/// Choose a proposer that is going to be the single leader (relevant for a mock fixed proposer
/// election only).
pub fn choose_leader(peers: Vec<Author>) -> Author {
// As it is just a tmp hack function, pick the min PeerId to be a proposer.
peers.into_iter().min().expect("No trusted peers found!")
}
impl RotatingProposer {
/// With only one proposer in the vector, it behaves the same as a fixed proposer strategy.
pub fn new(proposers: Vec<Author>, contiguous_rounds: u32) -> Self {
Self {
proposers,
contiguous_rounds,
}
}
}
impl ProposerElection for RotatingProposer {
fn get_valid_proposer(&self, round: Round) -> Author {
self.proposers
[((round / u64::from(self.contiguous_rounds)) % self.proposers.len() as u64) as usize]
}
}