Skip to content

Commit 76d31cd

Browse files
[Altair] Rewards tests (#2349)
* Rewards tests (base-only so far) * Altair rewards tests, clean-ups * Bump Rust version in Dockerfile
1 parent 6f6eebf commit 76d31cd

File tree

10 files changed

+368
-88
lines changed

10 files changed

+368
-88
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM rust:1.50.0 AS builder
1+
FROM rust:1.52.1 AS builder
22
RUN apt-get update && apt-get install -y cmake
33
COPY . lighthouse
44
ARG PORTABLE

consensus/state_processing/src/per_epoch_processing.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
pub use base::{TotalBalances, ValidatorStatus, ValidatorStatuses};
55
use errors::EpochProcessingError as Error;
66
pub use registry_updates::process_registry_updates;
7+
use safe_arith::SafeArith;
78
pub use slashings::process_slashings;
89
use types::{BeaconState, ChainSpec, EthSpec};
910
pub use weigh_justification_and_finalization::weigh_justification_and_finalization;
@@ -39,3 +40,30 @@ pub fn process_epoch<T: EthSpec>(
3940
BeaconState::Altair(_) => altair::process_epoch(state, spec),
4041
}
4142
}
43+
44+
/// Used to track the changes to a validator's balance.
45+
#[derive(Default, Clone)]
46+
pub struct Delta {
47+
pub rewards: u64,
48+
pub penalties: u64,
49+
}
50+
51+
impl Delta {
52+
/// Reward the validator with the `reward`.
53+
pub fn reward(&mut self, reward: u64) -> Result<(), Error> {
54+
self.rewards = self.rewards.safe_add(reward)?;
55+
Ok(())
56+
}
57+
58+
/// Penalize the validator with the `penalty`.
59+
pub fn penalize(&mut self, penalty: u64) -> Result<(), Error> {
60+
self.penalties = self.penalties.safe_add(penalty)?;
61+
Ok(())
62+
}
63+
64+
/// Combine two deltas.
65+
fn combine(&mut self, other: Delta) -> Result<(), Error> {
66+
self.reward(other.rewards)?;
67+
self.penalize(other.penalties)
68+
}
69+
}

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

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,7 @@ use types::consts::altair::{
66
use types::{BeaconState, ChainSpec, EthSpec};
77

88
use crate::common::{altair::get_base_reward, decrease_balance, increase_balance};
9-
use crate::per_epoch_processing::Error;
10-
11-
/// Use to track the changes to a validators balance.
12-
#[derive(Default, Clone)]
13-
pub struct Delta {
14-
rewards: u64,
15-
penalties: u64,
16-
}
17-
18-
impl Delta {
19-
/// Reward the validator with the `reward`.
20-
pub fn reward(&mut self, reward: u64) -> Result<(), Error> {
21-
self.rewards = self.rewards.safe_add(reward)?;
22-
Ok(())
23-
}
24-
25-
/// Penalize the validator with the `penalty`.
26-
pub fn penalize(&mut self, penalty: u64) -> Result<(), Error> {
27-
self.penalties = self.penalties.safe_add(penalty)?;
28-
Ok(())
29-
}
30-
31-
/// Combine two deltas.
32-
fn combine(&mut self, other: Delta) -> Result<(), Error> {
33-
self.reward(other.rewards)?;
34-
self.penalize(other.penalties)
35-
}
36-
}
9+
use crate::per_epoch_processing::{Delta, Error};
3710

3811
/// Apply attester and proposer rewards.
3912
///
@@ -76,9 +49,9 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
7649
/// Return the deltas for a given flag index by scanning through the participation flags.
7750
///
7851
/// Spec v1.1.0
79-
fn get_flag_index_deltas<T: EthSpec>(
52+
pub fn get_flag_index_deltas<T: EthSpec>(
8053
deltas: &mut Vec<Delta>,
81-
state: &mut BeaconState<T>,
54+
state: &BeaconState<T>,
8255
flag_index: u32,
8356
weight: u64,
8457
total_active_balance: u64,
@@ -119,7 +92,7 @@ fn get_flag_index_deltas<T: EthSpec>(
11992
Ok(())
12093
}
12194

122-
fn get_inactivity_penalty_deltas<T: EthSpec>(
95+
pub fn get_inactivity_penalty_deltas<T: EthSpec>(
12396
deltas: &mut Vec<Delta>,
12497
state: &BeaconState<T>,
12598
total_active_balance: u64,

consensus/state_processing/src/per_epoch_processing/base/rewards_and_penalties.rs

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,48 @@ use crate::common::{base::get_base_reward, decrease_balance, increase_balance};
22
use crate::per_epoch_processing::validator_statuses::{
33
TotalBalances, ValidatorStatus, ValidatorStatuses,
44
};
5-
use crate::per_epoch_processing::Error;
5+
use crate::per_epoch_processing::{Delta, Error};
66
use safe_arith::SafeArith;
7+
use std::array::IntoIter as ArrayIter;
78
use types::{BeaconState, ChainSpec, EthSpec};
89

9-
/// Use to track the changes to a validators balance.
10+
/// Combination of several deltas for different components of an attestation reward.
11+
///
12+
/// Exists only for compatibility with EF rewards tests.
1013
#[derive(Default, Clone)]
11-
pub struct Delta {
12-
rewards: u64,
13-
penalties: u64,
14+
pub struct AttestationDelta {
15+
pub source_delta: Delta,
16+
pub target_delta: Delta,
17+
pub head_delta: Delta,
18+
pub inclusion_delay_delta: Delta,
19+
pub inactivity_penalty_delta: Delta,
1420
}
1521

16-
impl Delta {
17-
/// Reward the validator with the `reward`.
18-
pub fn reward(&mut self, reward: u64) -> Result<(), Error> {
19-
self.rewards = self.rewards.safe_add(reward)?;
20-
Ok(())
21-
}
22-
23-
/// Penalize the validator with the `penalty`.
24-
pub fn penalize(&mut self, penalty: u64) -> Result<(), Error> {
25-
self.penalties = self.penalties.safe_add(penalty)?;
26-
Ok(())
27-
}
28-
29-
/// Combine two deltas.
30-
fn combine(&mut self, other: Delta) -> Result<(), Error> {
31-
self.reward(other.rewards)?;
32-
self.penalize(other.penalties)
22+
impl AttestationDelta {
23+
/// Flatten into a single delta.
24+
pub fn flatten(self) -> Result<Delta, Error> {
25+
let AttestationDelta {
26+
source_delta,
27+
target_delta,
28+
head_delta,
29+
inclusion_delay_delta,
30+
inactivity_penalty_delta,
31+
} = self;
32+
let mut result = Delta::default();
33+
for delta in ArrayIter::new([
34+
source_delta,
35+
target_delta,
36+
head_delta,
37+
inclusion_delay_delta,
38+
inactivity_penalty_delta,
39+
]) {
40+
result.combine(delta)?;
41+
}
42+
Ok(result)
3343
}
3444
}
3545

3646
/// Apply attester and proposer rewards.
37-
///
38-
/// Spec v0.12.1
3947
pub fn process_rewards_and_penalties<T: EthSpec>(
4048
state: &mut BeaconState<T>,
4149
validator_statuses: &mut ValidatorStatuses,
@@ -56,28 +64,27 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
5664

5765
// Apply the deltas, erroring on overflow above but not on overflow below (saturating at 0
5866
// instead).
59-
for (i, delta) in deltas.iter().enumerate() {
60-
increase_balance(state, i, delta.rewards)?;
61-
decrease_balance(state, i, delta.penalties)?;
67+
for (i, delta) in deltas.into_iter().enumerate() {
68+
let combined_delta = delta.flatten()?;
69+
increase_balance(state, i, combined_delta.rewards)?;
70+
decrease_balance(state, i, combined_delta.penalties)?;
6271
}
6372

6473
Ok(())
6574
}
6675

6776
/// Apply rewards for participation in attestations during the previous epoch.
68-
///
69-
/// Spec v0.12.1
70-
fn get_attestation_deltas<T: EthSpec>(
77+
pub fn get_attestation_deltas<T: EthSpec>(
7178
state: &BeaconState<T>,
7279
validator_statuses: &ValidatorStatuses,
7380
spec: &ChainSpec,
74-
) -> Result<Vec<Delta>, Error> {
81+
) -> Result<Vec<AttestationDelta>, Error> {
7582
let finality_delay = state
7683
.previous_epoch()
7784
.safe_sub(state.finalized_checkpoint().epoch)?
7885
.as_u64();
7986

80-
let mut deltas = vec![Delta::default(); state.validators().len()];
87+
let mut deltas = vec![AttestationDelta::default(); state.validators().len()];
8188

8289
let total_balances = &validator_statuses.total_balances;
8390

@@ -106,16 +113,19 @@ fn get_attestation_deltas<T: EthSpec>(
106113
let delta = deltas
107114
.get_mut(index)
108115
.ok_or(Error::DeltaOutOfBounds(index))?;
109-
delta.combine(source_delta)?;
110-
delta.combine(target_delta)?;
111-
delta.combine(head_delta)?;
112-
delta.combine(inclusion_delay_delta)?;
113-
delta.combine(inactivity_penalty_delta)?;
116+
delta.source_delta.combine(source_delta)?;
117+
delta.target_delta.combine(target_delta)?;
118+
delta.head_delta.combine(head_delta)?;
119+
delta.inclusion_delay_delta.combine(inclusion_delay_delta)?;
120+
delta
121+
.inactivity_penalty_delta
122+
.combine(inactivity_penalty_delta)?;
114123

115124
if let Some((proposer_index, proposer_delta)) = proposer_delta {
116125
deltas
117126
.get_mut(proposer_index)
118127
.ok_or(Error::ValidatorStatusesInconsistent)?
128+
.inclusion_delay_delta
119129
.combine(proposer_delta)?;
120130
}
121131
}

testing/ef_tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ fake_crypto = ["bls/fake_crypto"]
1313
[dependencies]
1414
bls = { path = "../../crypto/bls", default-features = false }
1515
compare_fields = { path = "../../common/compare_fields" }
16+
compare_fields_derive = { path = "../../common/compare_fields_derive" }
1617
derivative = "2.1.1"
1718
ethereum-types = "0.9.2"
1819
hex = "0.4.2"

testing/ef_tests/src/cases.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mod fork;
1515
mod genesis_initialization;
1616
mod genesis_validity;
1717
mod operations;
18+
mod rewards;
1819
mod sanity_blocks;
1920
mod sanity_slots;
2021
mod shuffling;
@@ -32,6 +33,7 @@ pub use fork::ForkTest;
3233
pub use genesis_initialization::*;
3334
pub use genesis_validity::*;
3435
pub use operations::*;
36+
pub use rewards::RewardsTest;
3537
pub use sanity_blocks::*;
3638
pub use sanity_slots::*;
3739
pub use shuffling::*;

0 commit comments

Comments
 (0)