Skip to content

Commit 4fa189f

Browse files
committed
Refactor validator inclusion endpoint
1 parent f0696af commit 4fa189f

File tree

5 files changed

+129
-68
lines changed

5 files changed

+129
-68
lines changed

beacon_node/http_api/src/validator_inclusion.rs

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,46 @@ use eth2::{
44
lighthouse::{GlobalValidatorInclusionData, ValidatorInclusionData},
55
types::ValidatorId,
66
};
7-
use state_processing::per_epoch_processing::ValidatorStatuses;
8-
use types::{Epoch, EthSpec};
7+
use state_processing::per_epoch_processing::{process_epoch, EpochProcessingSummary};
8+
use types::{BeaconState, ChainSpec, Epoch, EthSpec};
9+
10+
fn end_of_epoch_state<T: BeaconChainTypes>(
11+
epoch: Epoch,
12+
chain: &BeaconChain<T>,
13+
) -> Result<BeaconState<T::EthSpec>, warp::reject::Rejection> {
14+
let target_slot = epoch.end_slot(T::EthSpec::slots_per_epoch());
15+
StateId::slot(target_slot).state(chain)
16+
}
17+
18+
fn get_epoch_processing_summary<T: EthSpec>(
19+
state: &mut BeaconState<T>,
20+
spec: &ChainSpec,
21+
) -> Result<EpochProcessingSummary, warp::reject::Rejection> {
22+
process_epoch(state, spec)
23+
.map_err(|e| warp_utils::reject::custom_server_error(format!("{:?}", e)))
24+
}
925

1026
/// Returns information about *all validators* (i.e., global) and how they performed during a given
1127
/// epoch.
1228
pub fn global_validator_inclusion_data<T: BeaconChainTypes>(
1329
epoch: Epoch,
1430
chain: &BeaconChain<T>,
1531
) -> Result<GlobalValidatorInclusionData, warp::Rejection> {
16-
let target_slot = epoch.end_slot(T::EthSpec::slots_per_epoch());
17-
18-
let state = StateId::slot(target_slot).state(chain)?;
19-
20-
let mut validator_statuses = ValidatorStatuses::new(&state, &chain.spec)
21-
.map_err(warp_utils::reject::beacon_state_error)?;
22-
validator_statuses
23-
.process_attestations(&state)
24-
.map_err(warp_utils::reject::beacon_state_error)?;
25-
26-
let totals = validator_statuses.total_balances;
32+
let mut state = end_of_epoch_state(epoch, chain)?;
33+
let summary = get_epoch_processing_summary(&mut state, &chain.spec)?;
2734

2835
Ok(GlobalValidatorInclusionData {
29-
current_epoch_active_gwei: totals.current_epoch(),
30-
previous_epoch_active_gwei: totals.previous_epoch(),
31-
current_epoch_attesting_gwei: totals.current_epoch_attesters(),
32-
current_epoch_target_attesting_gwei: totals.current_epoch_target_attesters(),
33-
previous_epoch_attesting_gwei: totals.previous_epoch_attesters(),
34-
previous_epoch_target_attesting_gwei: totals.previous_epoch_target_attesters(),
35-
previous_epoch_head_attesting_gwei: totals.previous_epoch_head_attesters(),
36+
current_epoch_active_gwei: summary.current_epoch_total_active_balance(),
37+
previous_epoch_active_gwei: summary.previous_epoch_total_active_balance(),
38+
current_epoch_target_attesting_gwei: summary
39+
.current_epoch_target_attesting_balance()
40+
.map_err(|e| warp_utils::reject::custom_server_error(format!("{:?}", e)))?,
41+
previous_epoch_target_attesting_gwei: summary
42+
.previous_epoch_target_attesting_balance()
43+
.map_err(|e| warp_utils::reject::custom_server_error(format!("{:?}", e)))?,
44+
previous_epoch_head_attesting_gwei: summary
45+
.previous_epoch_head_attesting_balance()
46+
.map_err(|e| warp_utils::reject::custom_server_error(format!("{:?}", e)))?,
3647
})
3748
}
3849

@@ -42,15 +53,7 @@ pub fn validator_inclusion_data<T: BeaconChainTypes>(
4253
validator_id: &ValidatorId,
4354
chain: &BeaconChain<T>,
4455
) -> Result<Option<ValidatorInclusionData>, warp::Rejection> {
45-
let target_slot = epoch.end_slot(T::EthSpec::slots_per_epoch());
46-
47-
let mut state = StateId::slot(target_slot).state(chain)?;
48-
49-
let mut validator_statuses = ValidatorStatuses::new(&state, &chain.spec)
50-
.map_err(warp_utils::reject::beacon_state_error)?;
51-
validator_statuses
52-
.process_attestations(&state)
53-
.map_err(warp_utils::reject::beacon_state_error)?;
56+
let mut state = end_of_epoch_state(epoch, chain)?;
5457

5558
state
5659
.update_pubkey_cache()
@@ -70,19 +73,23 @@ pub fn validator_inclusion_data<T: BeaconChainTypes>(
7073
}
7174
};
7275

73-
Ok(validator_statuses
74-
.statuses
75-
.get(validator_index)
76-
.map(|vote| ValidatorInclusionData {
77-
is_slashed: vote.is_slashed,
78-
is_withdrawable_in_current_epoch: vote.is_withdrawable_in_current_epoch,
79-
is_active_in_current_epoch: vote.is_active_in_current_epoch,
80-
is_active_in_previous_epoch: vote.is_active_in_previous_epoch,
81-
current_epoch_effective_balance_gwei: vote.current_epoch_effective_balance,
82-
is_current_epoch_attester: vote.is_current_epoch_attester,
83-
is_current_epoch_target_attester: vote.is_current_epoch_target_attester,
84-
is_previous_epoch_attester: vote.is_previous_epoch_attester,
85-
is_previous_epoch_target_attester: vote.is_previous_epoch_target_attester,
86-
is_previous_epoch_head_attester: vote.is_previous_epoch_head_attester,
87-
}))
76+
let validator = if let Ok(validator) = state.get_validator(validator_index) {
77+
validator.clone()
78+
} else {
79+
return Ok(None);
80+
};
81+
82+
let summary = get_epoch_processing_summary(&mut state, &chain.spec)?;
83+
84+
Ok(Some(ValidatorInclusionData {
85+
is_slashed: validator.slashed,
86+
is_withdrawable_in_current_epoch: validator.is_withdrawable_at(epoch),
87+
is_active_in_current_epoch: summary.is_active_in_current_epoch(validator_index),
88+
is_active_in_previous_epoch: summary.is_active_in_previous_epoch(validator_index),
89+
current_epoch_effective_balance_gwei: validator.effective_balance,
90+
is_current_epoch_target_attester: summary.is_current_epoch_target_attester(validator_index),
91+
is_previous_epoch_target_attester: summary
92+
.is_previous_epoch_target_attester(validator_index),
93+
is_previous_epoch_head_attester: summary.is_previous_epoch_head_attester(validator_index),
94+
}))
8895
}

book/src/validator-inclusion.md

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,9 @@ The following fields are returned:
5252

5353
- `current_epoch_active_gwei`: the total staked gwei that was active (i.e.,
5454
able to vote) during the current epoch.
55-
- `current_epoch_attesting_gwei`: the total staked gwei that had one or more
56-
attestations included in a block during the current epoch (multiple
57-
attestations by the same validator do not increase this figure).
5855
- `current_epoch_target_attesting_gwei`: the total staked gwei that attested to
59-
the majority-elected Casper FFG target epoch during the current epoch. This
60-
figure must be equal to or less than `current_epoch_attesting_gwei`.
61-
- `previous_epoch_active_gwei`: as above, but during the previous epoch.
62-
- `previous_epoch_attesting_gwei`: see `current_epoch_attesting_gwei`.
56+
the majority-elected Casper FFG target epoch during the current epoch.
57+
- `previous_epoch_active_gwei`: as per `current_epoch_active_gwei`, but during the previous epoch.
6358
- `previous_epoch_target_attesting_gwei`: see `current_epoch_target_attesting_gwei`.
6459
- `previous_epoch_head_attesting_gwei`: the total staked gwei that attested to a
6560
head beacon block that is in the canonical chain.
@@ -91,9 +86,7 @@ curl -X GET "http://localhost:5052/lighthouse/validator_inclusion/0/global" -H
9186
"data": {
9287
"current_epoch_active_gwei": 642688000000000,
9388
"previous_epoch_active_gwei": 642688000000000,
94-
"current_epoch_attesting_gwei": 366208000000000,
9589
"current_epoch_target_attesting_gwei": 366208000000000,
96-
"previous_epoch_attesting_gwei": 1000000000,
9790
"previous_epoch_target_attesting_gwei": 1000000000,
9891
"previous_epoch_head_attesting_gwei": 1000000000
9992
}
@@ -124,9 +117,7 @@ curl -X GET "http://localhost:5052/lighthouse/validator_inclusion/0/42" -H "acc
124117
"is_active_in_current_epoch": true,
125118
"is_active_in_previous_epoch": true,
126119
"current_epoch_effective_balance_gwei": 32000000000,
127-
"is_current_epoch_attester": false,
128120
"is_current_epoch_target_attester": false,
129-
"is_previous_epoch_attester": false,
130121
"is_previous_epoch_target_attester": false,
131122
"is_previous_epoch_head_attester": false
132123
}

common/eth2/src/lighthouse.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,9 @@ pub struct GlobalValidatorInclusionData {
3232
pub current_epoch_active_gwei: u64,
3333
/// The total effective balance of all active validators during the _previous_ epoch.
3434
pub previous_epoch_active_gwei: u64,
35-
/// The total effective balance of all validators who attested during the _current_ epoch.
36-
pub current_epoch_attesting_gwei: u64,
3735
/// The total effective balance of all validators who attested during the _current_ epoch and
3836
/// agreed with the state about the beacon block at the first slot of the _current_ epoch.
3937
pub current_epoch_target_attesting_gwei: u64,
40-
/// The total effective balance of all validators who attested during the _previous_ epoch.
41-
pub previous_epoch_attesting_gwei: u64,
4238
/// The total effective balance of all validators who attested during the _previous_ epoch and
4339
/// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
4440
pub previous_epoch_target_attesting_gwei: u64,
@@ -59,13 +55,9 @@ pub struct ValidatorInclusionData {
5955
pub is_active_in_previous_epoch: bool,
6056
/// The validator's effective balance in the _current_ epoch.
6157
pub current_epoch_effective_balance_gwei: u64,
62-
/// True if the validator had an attestation included in the _current_ epoch.
63-
pub is_current_epoch_attester: bool,
6458
/// True if the validator's beacon block root attestation for the first slot of the _current_
6559
/// epoch matches the block root known to the state.
6660
pub is_current_epoch_target_attester: bool,
67-
/// True if the validator had an attestation included in the _previous_ epoch.
68-
pub is_previous_epoch_attester: bool,
6961
/// True if the validator's beacon block root attestation for the first slot of the _previous_
7062
/// epoch matches the block root known to the state.
7163
pub is_previous_epoch_target_attester: bool,

consensus/state_processing/src/per_epoch_processing/altair/participation_cache.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,22 @@ impl ParticipationCache {
226226
&self.eligible_indices
227227
}
228228

229+
pub fn current_epoch_total_active_balance(&self) -> u64 {
230+
self.current_epoch_participation.total_active_balance.get()
231+
}
232+
233+
fn current_epoch_flag_attesting_balance(&self, flag_index: usize) -> Result<u64, ArithError> {
234+
self.current_epoch_participation
235+
.total_flag_balances
236+
.get(flag_index)
237+
.map(Balance::get)
238+
.ok_or(ArithError::Overflow)
239+
}
240+
241+
pub fn current_epoch_target_attesting_balance(&self) -> Result<u64, ArithError> {
242+
self.current_epoch_flag_attesting_balance(TIMELY_TARGET_FLAG_INDEX)
243+
}
244+
229245
pub fn previous_epoch_total_active_balance(&self) -> u64 {
230246
self.previous_epoch_participation.total_active_balance.get()
231247
}
@@ -246,10 +262,6 @@ impl ParticipationCache {
246262
self.previous_epoch_flag_attesting_balance(TIMELY_HEAD_FLAG_INDEX)
247263
}
248264

249-
pub fn current_epoch_total_active_balance(&self) -> u64 {
250-
self.current_epoch_participation.total_active_balance.get()
251-
}
252-
253265
/// Equivalent to the `get_unslashed_participating_indices` function in the specification.
254266
pub fn get_unslashed_participating_indices(
255267
&self,

consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,29 @@ pub enum EpochProcessingSummary {
1818
}
1919

2020
impl EpochProcessingSummary {
21+
/// Returns the sum of the effective balance of all validators in the current epoch.
22+
pub fn current_epoch_total_active_balance(&self) -> u64 {
23+
match self {
24+
EpochProcessingSummary::Base { total_balances, .. } => total_balances.current_epoch(),
25+
EpochProcessingSummary::Altair {
26+
participation_cache,
27+
} => participation_cache.current_epoch_total_active_balance(),
28+
}
29+
}
30+
31+
/// Returns the sum of the effective balance of all validators in the current epoch who
32+
/// included an attestation that matched the target.
33+
pub fn current_epoch_target_attesting_balance(&self) -> Result<u64, ArithError> {
34+
match self {
35+
EpochProcessingSummary::Base { total_balances, .. } => {
36+
Ok(total_balances.current_epoch_target_attesters())
37+
}
38+
EpochProcessingSummary::Altair {
39+
participation_cache,
40+
} => participation_cache.current_epoch_target_attesting_balance(),
41+
}
42+
}
43+
2144
/// Returns the sum of the effective balance of all validators in the previous epoch.
2245
pub fn previous_epoch_total_active_balance(&self) -> u64 {
2346
match self {
@@ -28,6 +51,42 @@ impl EpochProcessingSummary {
2851
}
2952
}
3053

54+
/// Returns `true` if `val_index` was included in the active validator indices in the current
55+
/// epoch.
56+
///
57+
/// ## Notes
58+
///
59+
/// Always returns `false` for an unknown `val_index`.
60+
pub fn is_active_in_current_epoch(&self, val_index: usize) -> bool {
61+
match self {
62+
EpochProcessingSummary::Base { statuses, .. } => statuses
63+
.get(val_index)
64+
.map_or(false, |s| s.is_current_epoch_target_attester),
65+
EpochProcessingSummary::Altair {
66+
participation_cache,
67+
..
68+
} => participation_cache.is_active_in_current_epoch(val_index),
69+
}
70+
}
71+
72+
/// Returns `true` if `val_index` had a target-matching attestation included on chain in the
73+
/// current epoch.
74+
///
75+
/// ## Notes
76+
///
77+
/// Always returns `false` for an unknown `val_index`.
78+
pub fn is_current_epoch_target_attester(&self, val_index: usize) -> bool {
79+
match self {
80+
EpochProcessingSummary::Base { statuses, .. } => statuses
81+
.get(val_index)
82+
.map_or(false, |s| s.is_current_epoch_target_attester),
83+
EpochProcessingSummary::Altair {
84+
participation_cache,
85+
..
86+
} => participation_cache.is_current_epoch_timely_target_attester(val_index),
87+
}
88+
}
89+
3190
/// Returns the sum of the effective balance of all validators in the previous epoch who
3291
/// included an attestation that matched the target.
3392
pub fn previous_epoch_target_attesting_balance(&self) -> Result<u64, ArithError> {
@@ -69,7 +128,7 @@ impl EpochProcessingSummary {
69128
match self {
70129
EpochProcessingSummary::Base { statuses, .. } => statuses
71130
.get(val_index)
72-
.map_or(false, |s| s.is_previous_epoch_target_attester),
131+
.map_or(false, |s| s.is_active_in_previous_epoch),
73132
EpochProcessingSummary::Altair {
74133
participation_cache,
75134
..

0 commit comments

Comments
 (0)