Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Organize validator set #561

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 6 additions & 8 deletions core/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use ckey::Ed25519Public as Public;
use coordinator::engine::{BlockExecutor, ExecutionId};
use coordinator::types::Event;
use coordinator::{Header as PreHeader, Transaction, TransactionWithMetadata};
use cstate::{CurrentValidatorSet, NextValidatorSet, StateDB, StateError, StateWithCache, TopLevelState, TopState};
use cstate::{StateDB, StateError, StateValidatorSet, StateWithCache, TopLevelState, TopState};
use ctypes::header::{Header, Seal};
use ctypes::util::unexpected::Mismatch;
use ctypes::{ChainParams, CompactValidatorSet, TxHash};
Expand Down Expand Up @@ -233,7 +233,7 @@ impl OpenBlock {
let updated_validator_set = block_outcome.updated_validator_set;
let next_validator_set_hash = match updated_validator_set {
Some(ref set) => set.hash(),
None => NextValidatorSet::load_from_state(self.block.state())?.create_compact_validator_set().hash(),
None => StateValidatorSet::load_from_state(self.block.state(), false)?.hash(),
};
let updated_chain_params = block_outcome.updated_chain_params;
if let Err(e) = self.update_next_block_state(updated_validator_set, updated_chain_params) {
Expand Down Expand Up @@ -293,10 +293,8 @@ impl OpenBlock {

// called on open_block
fn update_current_validator_set(&mut self) -> Result<(), Error> {
let mut current_validators = CurrentValidatorSet::load_from_state(&self.state())?;
current_validators.update(NextValidatorSet::load_from_state(&self.state())?);
current_validators.save_to_state(self.inner_mut().state_mut())?;

let current_validators = StateValidatorSet::load_from_state(&self.state(), false)?;
current_validators.save_to_state(self.inner_mut().state_mut(), true)?;
Ok(())
}

Expand All @@ -309,8 +307,8 @@ impl OpenBlock {
let state = self.block.state_mut();

if let Some(set) = updated_validator_set {
let validators = NextValidatorSet::from_compact_validator_set(set);
validators.save_to_state(state)?;
let validators = StateValidatorSet::new(set.to_vec());
validators.save_to_state(state, false)?;
}

if let Some(params) = updated_chain_params {
Expand Down
6 changes: 3 additions & 3 deletions core/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use coordinator::engine::{BlockExecutor, GraphQlHandlerProvider, Initializer};
use coordinator::module::SessionId;
use coordinator::types::Event;
use coordinator::Transaction;
use cstate::{Metadata, NextValidatorSet, StateDB, StateWithCache, TopLevelState, TopState, TopStateView};
use cstate::{Metadata, StateDB, StateValidatorSet, StateWithCache, TopLevelState, TopState, TopStateView};
use ctimer::{TimeoutHandler, TimerApi, TimerScheduleError, TimerToken};
use ctypes::{BlockHash, BlockId, BlockNumber, ChainParams, Header, SyncHeader, TxHash};
use kvdb::{DBTransaction, KeyValueDB};
Expand Down Expand Up @@ -261,8 +261,8 @@ impl Client {

let (validators, chain_params) = coordinator.initialize_chain(&mut state);

let validator_set = NextValidatorSet::from_compact_validator_set(validators);
validator_set.save_to_state(&mut state)?;
let validator_set = StateValidatorSet::new(validators.to_vec());
validator_set.save_to_state(&mut state, false)?;

*state.get_metadata_mut().unwrap() = Metadata::new(chain_params);

Expand Down
8 changes: 4 additions & 4 deletions core/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use coordinator::test_coordinator::TestCoordinator;
use coordinator::types::Event;
use coordinator::Transaction;
use cstate::tests::helpers::empty_top_state_with_metadata;
use cstate::{NextValidatorSet, StateDB, TopLevelState};
use cstate::{StateDB, StateValidatorSet, TopLevelState};
use ctimer::{TimeoutHandler, TimerToken};
use ctypes::Header;
use ctypes::{
Expand Down Expand Up @@ -98,7 +98,7 @@ pub struct TestBlockChainClient {
/// Fixed validator keys
pub validator_keys: RwLock<HashMap<Public, Private>>,
/// Fixed validators
pub validators: NextValidatorSet,
pub validators: StateValidatorSet,
}

impl Default for TestBlockChainClient {
Expand Down Expand Up @@ -147,7 +147,7 @@ impl TestBlockChainClient {
history: RwLock::new(None),
term_id: Some(1),
validator_keys: RwLock::new(HashMap::new()),
validators: NextValidatorSet::from_compact_validator_set(CompactValidatorSet::new(Vec::new())),
validators: StateValidatorSet::new(Vec::new()),
};

// insert genesis hash.
Expand Down Expand Up @@ -285,7 +285,7 @@ impl TestBlockChainClient {
.collect(),
);

let fixed_validators: NextValidatorSet = NextValidatorSet::from_compact_validator_set(compact_validator_set);
let fixed_validators = StateValidatorSet::new(compact_validator_set.to_vec());

self.validators = fixed_validators
}
Expand Down
10 changes: 4 additions & 6 deletions core/src/consensus/tendermint/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::views::HeaderView;
use ckey::{verify, Ed25519Public as Public};
use cnetwork::NetworkService;
use crossbeam_channel as crossbeam;
use cstate::CurrentValidators;
use cstate::StateValidatorSet;
use ctypes::{util::unexpected::OutOfBounds, BlockHash, BlockId, CompactValidatorSet, Header, SyncHeader};
use std::iter::Iterator;
use std::sync::atomic::Ordering as AtomicOrdering;
Expand Down Expand Up @@ -277,11 +277,9 @@ impl ConsensusEngine for Tendermint {
Some(state) => state,
};
if block_number != Some(0) {
Ok(Some(
CurrentValidators::load_from_state(&state)
.expect("We read state from verified block")
.create_compact_validator_set(),
))
Ok(Some(CompactValidatorSet::new(
StateValidatorSet::load_from_state(&state, true).expect("We read state from verified block").to_vec(),
)))
} else {
Ok(None)
}
Expand Down
40 changes: 17 additions & 23 deletions core/src/consensus/validator_set/dynamic_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ use crate::client::ConsensusClient;
use crate::consensus::bit_set::BitSet;
use crate::consensus::EngineError;
use ckey::Ed25519Public as Public;
use cstate::{CurrentValidatorSet, NextValidatorSet, SimpleValidator};
use cstate::StateValidatorSet;
use ctypes::util::unexpected::OutOfBounds;
use ctypes::BlockHash;
use ctypes::CompactValidatorEntry;
use parking_lot::RwLock;
use std::cmp::Reverse;
use std::sync::{Arc, Weak};
Expand All @@ -46,41 +47,34 @@ impl WeightOrderedValidators {
}

impl DynamicValidator {
fn next_validators(&self, hash: BlockHash) -> Vec<SimpleValidator> {
fn next_validators(&self, hash: BlockHash) -> Vec<CompactValidatorEntry> {
let client: Arc<dyn ConsensusClient> =
self.client.read().as_ref().and_then(Weak::upgrade).expect("Client is not initialized");
let block_id = hash.into();
let state = client.state_at(block_id).expect("The next validators must be called on the confirmed block");
let validators = NextValidatorSet::load_from_state(&state).unwrap();
validators.into()
let validators = StateValidatorSet::load_from_state(&state, false).unwrap();
validators.to_vec()
}

fn current_validators(&self, hash: BlockHash) -> Vec<SimpleValidator> {
fn current_validators(&self, hash: BlockHash) -> Vec<CompactValidatorEntry> {
let client: Arc<dyn ConsensusClient> =
self.client.read().as_ref().and_then(Weak::upgrade).expect("Client is not initialized");
let block_id = hash.into();
let state = client.state_at(block_id).expect("The current validators must be called on the confirmed block");
let validators = CurrentValidatorSet::load_from_state(&state).unwrap();
validators.into()
let validators = StateValidatorSet::load_from_state(&state, true).unwrap();
validators.to_vec()
}

fn validators(&self, hash: BlockHash) -> Vec<Public> {
let validators = self.next_validators(hash);
validators.into_iter().map(|val| *val.pubkey()).collect()
validators.into_iter().map(|val| val.public_key).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())
validators.sort_unstable_by_key(|v| Reverse(v.delegation));
WeightOrderedValidators(validators.into_iter().map(|val| val.public_key).collect())
}

pub fn proposer_index(&self, parent: BlockHash, proposed_view: u64) -> usize {
Expand All @@ -91,7 +85,7 @@ impl DynamicValidator {
pub fn get_current(&self, hash: &BlockHash, index: usize) -> Public {
let validators = self.current_validators(*hash);
let n_validators = validators.len();
*validators.get(index % n_validators).unwrap().pubkey()
validators.get(index % n_validators).unwrap().public_key
}

pub fn check_enough_votes_with_current(&self, hash: &BlockHash, votes: &BitSet) -> Result<(), EngineError> {
Expand All @@ -106,9 +100,9 @@ impl DynamicValidator {
index,
}
})?;
voted_weight += validator.weight();
voted_weight += validator.delegation
}
let total_weight: u64 = validators.iter().map(|v| v.weight()).sum();
let total_weight: u64 = validators.iter().map(|v| v.delegation).sum();
if voted_weight * 3 > total_weight * 2 {
Ok(())
} else {
Expand Down Expand Up @@ -161,9 +155,9 @@ impl ValidatorSet for DynamicValidator {
index,
}
})?;
voted_weight += validator.weight();
voted_weight += validator.delegation;
}
let total_weight: u64 = validators.iter().map(SimpleValidator::weight).sum();
let total_weight: u64 = validators.iter().map(|x| x.delegation).sum();
if voted_weight * 3 > total_weight * 2 {
Ok(())
} else {
Expand All @@ -184,7 +178,7 @@ impl ValidatorSet for DynamicValidator {
}

fn current_validators(&self, hash: &BlockHash) -> Vec<Public> {
DynamicValidator::current_validators(self, *hash).into_iter().map(|v| *v.pubkey()).collect()
DynamicValidator::current_validators(self, *hash).into_iter().map(|v| v.public_key).collect()
}

fn next_validators(&self, hash: &BlockHash) -> Vec<Public> {
Expand Down
2 changes: 2 additions & 0 deletions state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.5", tag =
rlp_derive = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.5", tag = "v0.5.0"}
rustc-hex = "1.0"
remote-trait-object = "0.4.2"
serde = { version = "1.0.111", features = ["derive"] }
serde_cbor = "0.11.1"

[dev-dependencies]
rand = "0.6.1"
Expand Down
1 change: 0 additions & 1 deletion state/src/item/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ pub mod metadata;
pub mod module;
pub mod module_datum;
pub mod stake;
pub mod validator_set;

#[derive(Clone, Copy)]
#[repr(u8)]
Expand Down
Loading