Skip to content

Commit 666512e

Browse files
committed
Introduce CurrentValidators
CurrentValidators represent the list of validators for the current block. Its value is the same as the NextValidators of the previous block's state.
1 parent b0165a1 commit 666512e

File tree

4 files changed

+75
-29
lines changed

4 files changed

+75
-29
lines changed

core/src/client/test_client.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::client::{
5858
AccountData, BlockChainClient, BlockChainTrait, BlockProducer, BlockStatus, ConsensusClient, EngineInfo,
5959
ImportBlock, ImportResult, MiningBlockChainClient, StateInfo, StateOrBlock, TermInfo,
6060
};
61-
use crate::consensus::stake::{Validator, Validators};
61+
use crate::consensus::stake::{NextValidators, Validator};
6262
use crate::consensus::EngineError;
6363
use crate::db::{COL_STATE, NUM_COLUMNS};
6464
use crate::encoded;
@@ -105,7 +105,7 @@ pub struct TestBlockChainClient {
105105
/// Fixed validator keys
106106
pub validator_keys: RwLock<HashMap<Public, Private>>,
107107
/// Fixed validators
108-
pub validators: Validators,
108+
pub validators: NextValidators,
109109
}
110110

111111
impl Default for TestBlockChainClient {
@@ -159,7 +159,7 @@ impl TestBlockChainClient {
159159
history: RwLock::new(None),
160160
term_id: Some(1),
161161
validator_keys: RwLock::new(HashMap::new()),
162-
validators: Validators::from_vector_to_test(vec![]),
162+
validators: NextValidators::from_vector_to_test(vec![]),
163163
};
164164

165165
// insert genesis hash.
@@ -324,14 +324,14 @@ impl TestBlockChainClient {
324324
self.validator_keys.write().insert(*key_pair.public(), *key_pair.private());
325325
pubkeys.push(*key_pair.public());
326326
}
327-
let fixed_validators: Validators = Validators::from_vector_to_test(
327+
let fixed_validators: NextValidators = NextValidators::from_vector_to_test(
328328
pubkeys.into_iter().map(|pubkey| Validator::new_for_test(0, 0, pubkey)).collect(),
329329
);
330330

331331
self.validators = fixed_validators;
332332
}
333333

334-
pub fn get_validators(&self) -> &Validators {
334+
pub fn get_validators(&self) -> &NextValidators {
335335
&self.validators
336336
}
337337
}

core/src/consensus/stake/action_data.rs

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ lazy_static! {
4242
pub static ref JAIL_KEY: H256 = ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"Jail").into_key();
4343
pub static ref BANNED_KEY: H256 =
4444
ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"Banned").into_key();
45-
pub static ref VALIDATORS_KEY: H256 =
45+
pub static ref NEXT_VALIDATORS_KEY: H256 =
4646
ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"Validators").into_key();
47+
pub static ref CURRENT_VALIDATORS_KEY: H256 =
48+
ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"CurrentValidators").into_key();
4749
}
4850

4951
pub fn get_delegation_key(address: &Address) -> H256 {
@@ -275,17 +277,17 @@ impl Validator {
275277
}
276278

277279
#[derive(Debug)]
278-
pub struct Validators(Vec<Validator>);
279-
impl Validators {
280+
pub struct NextValidators(Vec<Validator>);
281+
impl NextValidators {
280282
pub fn from_vector_to_test(vec: Vec<Validator>) -> Self {
281-
Validators(vec)
283+
Self(vec)
282284
}
283285

284286
pub fn load_from_state(state: &TopLevelState) -> StateResult<Self> {
285-
let key = &*VALIDATORS_KEY;
287+
let key = &*NEXT_VALIDATORS_KEY;
286288
let validators = state.action_data(&key)?.map(|data| decode_list(&data)).unwrap_or_default();
287289

288-
Ok(Validators(validators))
290+
Ok(Self(validators))
289291
}
290292

291293
pub fn elect(state: &TopLevelState) -> StateResult<Self> {
@@ -336,7 +338,7 @@ impl Validators {
336338

337339

338340
pub fn save_to_state(&self, state: &mut TopLevelState) -> StateResult<()> {
339-
let key = &*VALIDATORS_KEY;
341+
let key = &*NEXT_VALIDATORS_KEY;
340342
if !self.is_empty() {
341343
state.update_action_data(&key, encode_list(&self.0).to_vec())?;
342344
} else {
@@ -385,21 +387,21 @@ impl Validators {
385387
}
386388
}
387389

388-
impl Deref for Validators {
390+
impl Deref for NextValidators {
389391
type Target = Vec<Validator>;
390392

391393
fn deref(&self) -> &Self::Target {
392394
&self.0
393395
}
394396
}
395397

396-
impl From<Validators> for Vec<Validator> {
397-
fn from(val: Validators) -> Self {
398+
impl From<NextValidators> for Vec<Validator> {
399+
fn from(val: NextValidators) -> Self {
398400
val.0
399401
}
400402
}
401403

402-
impl IntoIterator for Validators {
404+
impl IntoIterator for NextValidators {
403405
type Item = Validator;
404406
type IntoIter = vec::IntoIter<Self::Item>;
405407

@@ -408,6 +410,39 @@ impl IntoIterator for Validators {
408410
}
409411
}
410412

413+
#[derive(Debug)]
414+
pub struct CurrentValidators(Vec<Validator>);
415+
impl CurrentValidators {
416+
pub fn load_from_state(state: &TopLevelState) -> StateResult<Self> {
417+
let key = &*CURRENT_VALIDATORS_KEY;
418+
let validators = state.action_data(&key)?.map(|data| decode_list(&data)).unwrap_or_default();
419+
420+
Ok(Self(validators))
421+
}
422+
423+
pub fn save_to_state(&self, state: &mut TopLevelState) -> StateResult<()> {
424+
let key = &*CURRENT_VALIDATORS_KEY;
425+
if !self.is_empty() {
426+
state.update_action_data(&key, encode_list(&self.0).to_vec())?;
427+
} else {
428+
state.remove_action_data(&key);
429+
}
430+
Ok(())
431+
}
432+
433+
pub fn update(&mut self, validators: Vec<Validator>) {
434+
self.0 = validators;
435+
}
436+
}
437+
438+
impl Deref for CurrentValidators {
439+
type Target = Vec<Validator>;
440+
441+
fn deref(&self) -> &Self::Target {
442+
&self.0
443+
}
444+
}
445+
411446
#[derive(Default, Debug, PartialEq)]
412447
pub struct IntermediateRewards {
413448
pub(super) current: BTreeMap<Address, u64>,
@@ -544,7 +579,7 @@ impl Candidates {
544579

545580
pub fn renew_candidates(
546581
&mut self,
547-
validators: &Validators,
582+
validators: &NextValidators,
548583
nomination_ends_at: u64,
549584
inactive_validators: &[Address],
550585
banned: &Banned,
@@ -1754,7 +1789,7 @@ mod tests {
17541789
}
17551790
candidates.save_to_state(&mut state).unwrap();
17561791

1757-
let dummy_validators = Validators(
1792+
let dummy_validators = NextValidators(
17581793
pubkeys[0..5]
17591794
.iter()
17601795
.map(|pubkey| Validator {

core/src/consensus/stake/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use parking_lot::RwLock;
3333
use primitives::{Bytes, H256};
3434
use rlp::{Decodable, Rlp};
3535

36-
pub use self::action_data::{Banned, Validator, Validators};
36+
pub use self::action_data::{Banned, CurrentValidators, NextValidators, Validator};
3737
use self::action_data::{Candidates, Delegation, IntermediateRewards, Jail, ReleaseResult, StakeAccount, Stakeholders};
3838
pub use self::actions::Action;
3939
pub use self::distribute::fee_distribute;
@@ -317,8 +317,8 @@ pub fn get_stakes(state: &TopLevelState) -> StateResult<HashMap<Address, u64>> {
317317
Ok(result)
318318
}
319319

320-
pub fn get_validators(state: &TopLevelState) -> StateResult<Validators> {
321-
Validators::load_from_state(state)
320+
pub fn get_validators(state: &TopLevelState) -> StateResult<NextValidators> {
321+
NextValidators::load_from_state(state)
322322
}
323323

324324
pub fn add_intermediate_rewards(state: &mut TopLevelState, address: Address, reward: u64) -> StateResult<()> {
@@ -349,7 +349,7 @@ pub fn drain_calculated_rewards(state: &mut TopLevelState) -> StateResult<BTreeM
349349
}
350350

351351
pub fn update_validator_weights(state: &mut TopLevelState, block_author: &Address) -> StateResult<()> {
352-
let mut validators = Validators::load_from_state(state)?;
352+
let mut validators = NextValidators::load_from_state(state)?;
353353
validators.update_weight(block_author);
354354
validators.save_to_state(state)
355355
}
@@ -421,7 +421,7 @@ pub fn on_term_close(
421421

422422
jail(state, inactive_validators, custody_until, kick_at)?;
423423

424-
let validators = Validators::elect(state)?;
424+
let validators = NextValidators::elect(state)?;
425425
validators.save_to_state(state)?;
426426

427427
state.increase_term_id(last_term_finished_block_num)?;
@@ -439,7 +439,7 @@ fn update_candidates(
439439
let mut candidates = Candidates::load_from_state(state)?;
440440
let nomination_ends_at = current_term + nomination_expiration;
441441

442-
let current_validators = Validators::load_from_state(state)?;
442+
let current_validators = NextValidators::load_from_state(state)?;
443443
candidates.renew_candidates(&current_validators, nomination_ends_at, &inactive_validators, &banned);
444444

445445
let expired = candidates.drain_expired_candidates(current_term);
@@ -489,7 +489,7 @@ pub fn ban(state: &mut TopLevelState, informant: &Public, criminal: Address) ->
489489

490490
let mut candidates = Candidates::load_from_state(state)?;
491491
let mut jailed = Jail::load_from_state(state)?;
492-
let mut validators = Validators::load_from_state(state)?;
492+
let mut validators = NextValidators::load_from_state(state)?;
493493

494494
let deposit = match (candidates.remove(&criminal), jailed.remove(&criminal)) {
495495
(Some(_), Some(_)) => unreachable!("A candidate that are jailed cannot exist"),

core/src/consensus/tendermint/engine.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,25 @@ impl ConsensusEngine for Tendermint {
147147

148148
let block_number = block.header().number();
149149
let metadata = block.state().metadata()?.expect("Metadata must exist");
150+
let term = metadata.current_term_id();
151+
152+
match term {
153+
0 => {}
154+
_ => {
155+
let mut validators = stake::CurrentValidators::load_from_state(block.state())?;
156+
validators.update(stake::NextValidators::load_from_state(block.state())?.clone());
157+
validators.save_to_state(block.state_mut())?;
158+
}
159+
}
160+
150161
if block_number == metadata.last_term_finished_block_num() + 1 {
151-
match metadata.current_term_id() {
152-
0 => {},
162+
match term {
163+
0 => {}
153164
_ => {
154165
let rewards = stake::drain_current_rewards(block.state_mut())?;
155166
let banned = stake::Banned::load_from_state(block.state())?;
156167
let start_of_the_current_term_header =
157-
encoded::Header::new(block.header().clone().rlp_bytes().to_vec());
168+
encoded::Header::new(block.header().clone().rlp_bytes().to_vec());
158169

159170
let pending_rewards = calculate_pending_rewards_of_the_term(
160171
&*client,
@@ -231,7 +242,7 @@ impl ConsensusEngine for Tendermint {
231242
}
232243

233244
let start_of_the_current_term = metadata.last_term_finished_block_num() + 1;
234-
let validators = stake::Validators::load_from_state(block.state())?
245+
let validators = stake::NextValidators::load_from_state(block.state())?
235246
.into_iter()
236247
.map(|val| public_to_address(val.pubkey()))
237248
.collect();

0 commit comments

Comments
 (0)