Skip to content

Commit 46b3a46

Browse files
committed
Get tendermint validators with CurrentValidators
1 parent 666512e commit 46b3a46

File tree

7 files changed

+65
-30
lines changed

7 files changed

+65
-30
lines changed

core/src/consensus/simple_poa/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl ConsensusEngine for SimplePoA {
149149
fn possible_authors(&self, _block_number: Option<u64>) -> Result<Option<Vec<Address>>, EngineError> {
150150
// TODO: It works because the round robin validator doesn't use the parent hash.
151151
let parent = H256::from(0).into();
152-
Ok(Some(self.validators.addresses(&parent)))
152+
Ok(Some(self.validators.next_addresses(&parent)))
153153
}
154154
}
155155

core/src/consensus/stake/action_data.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,12 @@ impl Deref for CurrentValidators {
443443
}
444444
}
445445

446+
impl From<CurrentValidators> for Vec<Validator> {
447+
fn from(val: CurrentValidators) -> Self {
448+
val.0
449+
}
450+
}
451+
446452
#[derive(Default, Debug, PartialEq)]
447453
pub struct IntermediateRewards {
448454
pub(super) current: BTreeMap<Address, u64>,

core/src/consensus/stake/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,6 @@ pub fn get_stakes(state: &TopLevelState) -> StateResult<HashMap<Address, u64>> {
317317
Ok(result)
318318
}
319319

320-
pub fn get_validators(state: &TopLevelState) -> StateResult<NextValidators> {
321-
NextValidators::load_from_state(state)
322-
}
323-
324320
pub fn add_intermediate_rewards(state: &mut TopLevelState, address: Address, reward: u64) -> StateResult<()> {
325321
let mut rewards = IntermediateRewards::load_from_state(state)?;
326322
rewards.add_quantity(address, reward);

core/src/consensus/tendermint/engine.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ impl ConsensusEngine for Tendermint {
342342
client.block_header(&(block_number - 1).into()).ok_or(EngineError::CannotOpenBlock)?.hash() // the parent of the given block number
343343
}
344344
};
345-
Ok(Some(self.validators.addresses(&block_hash)))
345+
Ok(Some(self.validators.next_addresses(&block_hash)))
346346
}
347347
}
348348

@@ -389,23 +389,15 @@ fn aggregate_work_info(
389389
end_of_the_last_term + 1
390390
};
391391
let mut header = start_of_the_next_term_header;
392-
let mut parent_validators = {
393-
let parent_header = chain.block_header(&header.parent_hash().into()).unwrap();
394-
validators.addresses(&parent_header.parent_hash())
395-
};
392+
let mut parent_validators = validators.current_addresses(&header.parent_hash());
396393
while start_of_the_current_term != header.number() {
397394
for index in TendermintSealView::new(&header.seal()).bitset()?.true_index_iter() {
398395
let signer = *parent_validators.get(index).expect("The seal must be the signature of the validator");
399396
work_info.entry(signer).or_default().signed += 1;
400397
}
401398

402399
header = chain.block_header(&header.parent_hash().into()).unwrap();
403-
parent_validators = {
404-
// The seal of the current block has the signatures of the parent block.
405-
// It needs the hash of the grand parent block to find the validators of the parent block.
406-
let parent_header = chain.block_header(&header.parent_hash().into()).unwrap();
407-
validators.addresses(&parent_header.parent_hash())
408-
};
400+
parent_validators = validators.current_addresses(&header.parent_hash());
409401

410402
let author = header.author();
411403
let info = work_info.entry(author).or_default();

core/src/consensus/validator_set/dynamic_validator.rs

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use parking_lot::RwLock;
2424
use super::{RoundRobinValidator, ValidatorSet};
2525
use crate::client::ConsensusClient;
2626
use crate::consensus::bit_set::BitSet;
27-
use crate::consensus::stake::{get_validators, Validator};
27+
use crate::consensus::stake::{CurrentValidators, NextValidators, Validator};
2828
use crate::consensus::EngineError;
2929

3030
/// Validator set containing a known set of public keys.
@@ -41,10 +41,10 @@ impl DynamicValidator {
4141
}
4242
}
4343

44-
fn validators(&self, parent: BlockHash) -> Option<Vec<Validator>> {
44+
fn next_validators(&self, hash: BlockHash) -> Option<Vec<Validator>> {
4545
let client: Arc<dyn ConsensusClient> =
4646
self.client.read().as_ref().and_then(Weak::upgrade).expect("Client is not initialized");
47-
let block_id = parent.into();
47+
let block_id = hash.into();
4848
let term_id = client.current_term_id(block_id).expect(
4949
"valdators() is called when creating a block or verifying a block.
5050
Minor creates a block only when the parent block is imported.
@@ -54,7 +54,7 @@ impl DynamicValidator {
5454
return None
5555
}
5656
let state = client.state_at(block_id)?;
57-
let validators = get_validators(&state).unwrap();
57+
let validators = NextValidators::load_from_state(&state).unwrap();
5858
if validators.is_empty() {
5959
None
6060
} else {
@@ -64,12 +64,39 @@ impl DynamicValidator {
6464
}
6565
}
6666

67-
fn validators_pubkey(&self, parent: BlockHash) -> Option<Vec<Public>> {
68-
self.validators(parent).map(|validators| validators.into_iter().map(|val| *val.pubkey()).collect())
67+
fn current_validators(&self, hash: BlockHash) -> Option<Vec<Validator>> {
68+
let client: Arc<dyn ConsensusClient> =
69+
self.client.read().as_ref().and_then(Weak::upgrade).expect("Client is not initialized");
70+
let block_id = hash.into();
71+
let term_id = client.current_term_id(block_id).expect(
72+
"valdators() is called when creating a block or verifying a block.
73+
Minor creates a block only when the parent block is imported.
74+
The n'th block is verified only when the parent block is imported.",
75+
);
76+
if term_id == 0 {
77+
return None
78+
}
79+
let state = client.state_at(block_id)?;
80+
let validators = CurrentValidators::load_from_state(&state).unwrap();
81+
if validators.is_empty() {
82+
None
83+
} else {
84+
let mut validators: Vec<_> = validators.into();
85+
validators.reverse();
86+
Some(validators)
87+
}
88+
}
89+
90+
fn validators_pubkey(&self, hash: BlockHash) -> Option<Vec<Public>> {
91+
self.next_validators(hash).map(|validators| validators.into_iter().map(|val| *val.pubkey()).collect())
92+
}
93+
94+
fn current_validators_pubkey(&self, hash: BlockHash) -> Option<Vec<Public>> {
95+
self.current_validators(hash).map(|validators| validators.into_iter().map(|val| *val.pubkey()).collect())
6996
}
7097

7198
pub fn proposer_index(&self, parent: BlockHash, prev_proposer_index: usize, proposed_view: usize) -> usize {
72-
if let Some(validators) = self.validators(parent) {
99+
if let Some(validators) = self.next_validators(parent) {
73100
let num_validators = validators.len();
74101
proposed_view % num_validators
75102
} else {
@@ -136,15 +163,15 @@ impl ValidatorSet for DynamicValidator {
136163
}
137164

138165
fn count(&self, parent: &BlockHash) -> usize {
139-
if let Some(validators) = self.validators(*parent) {
166+
if let Some(validators) = self.next_validators(*parent) {
140167
validators.len()
141168
} else {
142169
self.initial_list.count(parent)
143170
}
144171
}
145172

146173
fn check_enough_votes(&self, parent: &BlockHash, votes: &BitSet) -> Result<(), EngineError> {
147-
if let Some(validators) = self.validators(*parent) {
174+
if let Some(validators) = self.next_validators(*parent) {
148175
let mut voted_delegation = 0u64;
149176
let n_validators = validators.len();
150177
for index in votes.true_index_iter() {
@@ -181,11 +208,19 @@ impl ValidatorSet for DynamicValidator {
181208
*client_lock = Some(client);
182209
}
183210

184-
fn addresses(&self, parent: &BlockHash) -> Vec<Address> {
185-
if let Some(validators) = self.validators_pubkey(*parent) {
211+
fn current_addresses(&self, hash: &BlockHash) -> Vec<Address> {
212+
if let Some(validators) = self.current_validators_pubkey(*hash) {
213+
validators.iter().map(public_to_address).collect()
214+
} else {
215+
self.initial_list.next_addresses(hash)
216+
}
217+
}
218+
219+
fn next_addresses(&self, hash: &BlockHash) -> Vec<Address> {
220+
if let Some(validators) = self.validators_pubkey(*hash) {
186221
validators.iter().map(public_to_address).collect()
187222
} else {
188-
self.initial_list.addresses(parent)
223+
self.initial_list.next_addresses(hash)
189224
}
190225
}
191226
}

core/src/consensus/validator_set/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,7 @@ pub trait ValidatorSet: Send + Sync {
5757
/// Allows blockchain state access.
5858
fn register_client(&self, _client: Weak<dyn ConsensusClient>) {}
5959

60-
fn addresses(&self, _parent: &BlockHash) -> Vec<Address>;
60+
fn current_addresses(&self, _hash: &BlockHash) -> Vec<Address>;
61+
62+
fn next_addresses(&self, _hash: &BlockHash) -> Vec<Address>;
6163
}

core/src/consensus/validator_set/validator_list.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ impl ValidatorSet for RoundRobinValidator {
105105
*self.client.write() = Some(client);
106106
}
107107

108-
fn addresses(&self, _parent: &BlockHash) -> Vec<Address> {
108+
fn current_addresses(&self, _hash: &BlockHash) -> Vec<Address> {
109+
self.validators.iter().map(public_to_address).collect()
110+
}
111+
112+
fn next_addresses(&self, _hash: &BlockHash) -> Vec<Address> {
109113
self.validators.iter().map(public_to_address).collect()
110114
}
111115
}

0 commit comments

Comments
 (0)