Skip to content

Commit

Permalink
Make Foundry use all validators as proposer
Browse files Browse the repository at this point in the history
This commit assumes that the validator set is not changed.
  • Loading branch information
majecty authored and mergify[bot] committed Dec 22, 2020
1 parent 7b43a89 commit c562483
Showing 1 changed file with 16 additions and 33 deletions.
49 changes: 16 additions & 33 deletions core/src/consensus/validator_set/dynamic_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,15 @@ use ckey::Ed25519Public as Public;
use cstate::{CurrentValidatorSet, NextValidatorSet, SimpleValidator};
use ctypes::util::unexpected::OutOfBounds;
use ctypes::BlockHash;
use ctypes::BlockId;
use parking_lot::RwLock;
use std::cmp::Reverse;
use std::sync::{Arc, Weak};

#[derive(Default)]
pub struct DynamicValidator {
client: RwLock<Option<Weak<dyn ConsensusClient>>>,
}

pub struct WeightOrderedValidators(Vec<Public>);

pub struct WeightIndex(usize);

impl WeightOrderedValidators {
pub fn len(&self) -> usize {
self.0.len()
}

pub fn get(&self, index: WeightIndex) -> Option<&Public> {
self.0.get(index.0)
}
}

impl DynamicValidator {
fn next_validators(&self, hash: BlockHash) -> Vec<SimpleValidator> {
let client: Arc<dyn ConsensusClient> =
Expand All @@ -69,20 +55,6 @@ impl DynamicValidator {
validators.into_iter().map(|val| *val.pubkey()).collect()
}

fn validators_order_by_weight(&self, hash: BlockHash) -> WeightOrderedValidators {
let mut validators = self.next_validators(hash);
// Should we cache the sorted validator?
validators.sort_unstable_by_key(|v| {
(
Reverse(v.weight()),
Reverse(v.deposit()),
v.nominated_at_block_number(),
v.nominated_at_transaction_index(),
)
});
WeightOrderedValidators(validators.into_iter().map(|val| *val.pubkey()).collect())
}

pub fn proposer_index(&self, parent: BlockHash, proposed_view: u64) -> usize {
let propser = self.next_block_proposer(&parent, proposed_view);
self.get_index(&parent, &propser).expect("We know propser is included in a validator set")
Expand Down Expand Up @@ -138,11 +110,22 @@ impl ValidatorSet for DynamicValidator {
self.validators(*parent).binary_search(public).ok()
}

// This code assumes that validator set is not changed.
// Later this code should be moved to UpdateConsensus
fn next_block_proposer(&self, parent: &BlockHash, view: u64) -> Public {
let validators = self.validators_order_by_weight(*parent);
let n_validators = validators.len();
let index = WeightIndex(view as usize % n_validators);
*validators.get(index).unwrap()
let client: Arc<dyn ConsensusClient> = self.client.read().as_ref().and_then(Weak::upgrade).unwrap();
let parent_header = client.block_header(&BlockId::from(*parent)).expect("Parent must be finalized");
if parent_header.number() == 0 {
return self.get(parent, 0)
}

let proposer = parent_header.author();
let grand_parent = parent_header.parent_hash();
let prev_proposer_idx =
self.get_index(&grand_parent, &proposer).expect("The proposer must be in the validator set");
let proposer_index = prev_proposer_idx + 1 + view as usize;
ctrace!(ENGINE, "Proposer index: {}", proposer_index);
self.get(&parent, proposer_index)
}

fn count(&self, parent: &BlockHash) -> usize {
Expand Down

0 comments on commit c562483

Please sign in to comment.