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 41 42 43 44 45 46 47
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/
use crate::pos::consensus::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]
}
}