Skip to content

Commit eb4963b

Browse files
bowenwang1996Bowen Wang
authored andcommitted
fix(rpc): fix inefficiency in get_validator_info (#3004)
Currently `get_validator_info` is hugely inefficient due to recalculation of the aggregator for every current validator. This potentially causes exorbitant rpc response time since each aggregator calculation is already expensive.
1 parent 4b1f0c2 commit eb4963b

1 file changed

Lines changed: 35 additions & 26 deletions

File tree

chain/epoch_manager/src/lib.rs

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -292,27 +292,6 @@ impl EpochManager {
292292
})
293293
}
294294

295-
/// Returns number of produced and expected blocks by given validator.
296-
fn get_num_validator_blocks(
297-
&mut self,
298-
epoch_id: &EpochId,
299-
last_known_block_hash: &CryptoHash,
300-
account_id: &AccountId,
301-
) -> Result<ValidatorStats, EpochError> {
302-
let epoch_info = self.get_epoch_info(&epoch_id)?;
303-
let validator_id = *epoch_info
304-
.validator_to_index
305-
.get(account_id)
306-
.ok_or_else(|| EpochError::NotAValidator(account_id.clone(), epoch_id.clone()))?;
307-
let aggregator =
308-
self.get_and_update_epoch_info_aggregator(epoch_id, last_known_block_hash, true)?;
309-
Ok(aggregator
310-
.block_tracker
311-
.get(&validator_id)
312-
.unwrap_or_else(|| &ValidatorStats { produced: 0, expected: 0 })
313-
.clone())
314-
}
315-
316295
/// Finalizes epoch (T), where given last block hash is given, and returns next next epoch id (T + 2).
317296
fn finalize_epoch(
318297
&mut self,
@@ -846,13 +825,18 @@ impl EpochManager {
846825
validator_to_shard[*validator_id as usize].insert(shard_id as ShardId);
847826
}
848827
}
828+
let epoch_info_aggregator =
829+
self.get_and_update_epoch_info_aggregator(&epoch_id, block_hash, true)?;
849830
let current_validators = cur_epoch_info
850831
.validators
851832
.into_iter()
852833
.enumerate()
853834
.map(|(validator_id, info)| {
854-
let validator_stats =
855-
self.get_num_validator_blocks(&epoch_id, &block_hash, &info.account_id)?;
835+
let validator_stats = epoch_info_aggregator
836+
.block_tracker
837+
.get(&(validator_id as u64))
838+
.unwrap_or_else(|| &ValidatorStats { produced: 0, expected: 0 })
839+
.clone();
856840
let mut shards =
857841
validator_to_shard[validator_id].clone().into_iter().collect::<Vec<ShardId>>();
858842
shards.sort();
@@ -906,15 +890,17 @@ impl EpochManager {
906890
.into_iter()
907891
.map(|(account_id, reason)| ValidatorKickoutView { account_id, reason })
908892
.collect();
909-
let current_proposals =
910-
self.get_and_update_epoch_info_aggregator(&epoch_id, block_hash, true)?.all_proposals;
911893

912894
Ok(EpochValidatorInfo {
913895
current_validators,
914896
next_validators,
915897
current_fishermen: current_fishermen.into_iter().map(Into::into).collect(),
916898
next_fishermen: next_fishermen.into_iter().map(Into::into).collect(),
917-
current_proposals: current_proposals.into_iter().map(|(_, p)| p.into()).collect(),
899+
current_proposals: epoch_info_aggregator
900+
.all_proposals
901+
.into_iter()
902+
.map(|(_, p)| p.into())
903+
.collect(),
918904
prev_epoch_kickout,
919905
epoch_start_height,
920906
})
@@ -1211,6 +1197,29 @@ mod tests {
12111197

12121198
use super::*;
12131199

1200+
impl EpochManager {
1201+
/// Returns number of produced and expected blocks by given validator.
1202+
fn get_num_validator_blocks(
1203+
&mut self,
1204+
epoch_id: &EpochId,
1205+
last_known_block_hash: &CryptoHash,
1206+
account_id: &AccountId,
1207+
) -> Result<ValidatorStats, EpochError> {
1208+
let epoch_info = self.get_epoch_info(&epoch_id)?;
1209+
let validator_id = *epoch_info
1210+
.validator_to_index
1211+
.get(account_id)
1212+
.ok_or_else(|| EpochError::NotAValidator(account_id.clone(), epoch_id.clone()))?;
1213+
let aggregator =
1214+
self.get_and_update_epoch_info_aggregator(epoch_id, last_known_block_hash, true)?;
1215+
Ok(aggregator
1216+
.block_tracker
1217+
.get(&validator_id)
1218+
.unwrap_or_else(|| &ValidatorStats { produced: 0, expected: 0 })
1219+
.clone())
1220+
}
1221+
}
1222+
12141223
#[test]
12151224
fn test_stake_validator() {
12161225
let amount_staked = 1_000_000;

0 commit comments

Comments
 (0)