2020-08-17 01:09:27 +00:00
|
|
|
# beacon_chain
|
|
|
|
# Copyright (c) 2020-Present Status Research & Development GmbH
|
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
|
|
|
# Standard library
|
|
|
|
os, unittest,
|
|
|
|
# Utilities
|
|
|
|
stew/results,
|
|
|
|
# Beacon chain internals
|
2020-10-22 11:08:46 +00:00
|
|
|
../../beacon_chain/spec/[validator, datatypes, helpers, state_transition_epoch],
|
2020-08-17 01:09:27 +00:00
|
|
|
../../beacon_chain/ssz,
|
|
|
|
# Test utilities
|
|
|
|
../testutil,
|
|
|
|
./fixtures_utils
|
|
|
|
|
2020-09-21 15:58:35 +00:00
|
|
|
const
|
|
|
|
RewardsDirBase = SszTestsDir/const_preset/"phase0"/"rewards"
|
|
|
|
RewardsDirBasic = RewardsDirBase/"basic"/"pyspec_tests"
|
|
|
|
RewardsDirLeak = RewardsDirBase/"leak"/"pyspec_tests"
|
|
|
|
RewardsDirRandom = RewardsDirBase/"random"/"pyspec_tests"
|
2020-08-17 01:09:27 +00:00
|
|
|
|
2020-11-09 17:44:18 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/tree/v1.0.0/tests/formats/rewards#rewards-tests
|
2020-08-17 01:09:27 +00:00
|
|
|
type Deltas = object
|
|
|
|
rewards: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT]
|
|
|
|
penalties: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT]
|
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
func add(v: var Deltas, idx: int, delta: Delta) =
|
|
|
|
v.rewards[idx] += delta.rewards
|
|
|
|
v.penalties[idx] += delta.penalties
|
|
|
|
|
|
|
|
func init(T: type Deltas, len: int): T =
|
|
|
|
result.rewards.setLen(len)
|
|
|
|
result.penalties.setLen(len)
|
2020-08-17 01:09:27 +00:00
|
|
|
|
2020-09-21 15:58:35 +00:00
|
|
|
proc runTest(rewardsDir, identifier: string) =
|
2020-08-17 01:09:27 +00:00
|
|
|
# We wrap the tests in a proc to avoid running out of globals
|
|
|
|
# in the future: Nim supports up to 3500 globals
|
|
|
|
# but unittest with the macro/templates put everything as globals
|
|
|
|
# https://github.com/nim-lang/Nim/issues/12084#issue-486866402
|
2020-09-21 15:58:35 +00:00
|
|
|
let testDir = rewardsDir / identifier
|
2020-08-17 01:09:27 +00:00
|
|
|
|
|
|
|
proc `testImpl _ rewards _ identifier`() =
|
|
|
|
timedTest "Rewards" & " - " & identifier & preset():
|
|
|
|
var
|
|
|
|
state = newClone(parseTest(testDir/"pre.ssz", SSZ, BeaconState))
|
|
|
|
cache = StateCache()
|
|
|
|
let
|
|
|
|
sourceDeltas = parseTest(testDir/"source_deltas.ssz", SSZ, Deltas)
|
|
|
|
targetDeltas = parseTest(testDir/"target_deltas.ssz", SSZ, Deltas)
|
|
|
|
headDeltas = parseTest(testDir/"head_deltas.ssz", SSZ, Deltas)
|
|
|
|
inclusionDelayDeltas =
|
|
|
|
parseTest(testDir/"inclusion_delay_deltas.ssz", SSZ, Deltas)
|
|
|
|
inactivityPenaltyDeltas =
|
|
|
|
parseTest(testDir/"inactivity_penalty_deltas.ssz", SSZ, Deltas)
|
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
var
|
|
|
|
validator_statuses = ValidatorStatuses.init(state[])
|
|
|
|
finality_delay = (state[].get_previous_epoch() - state[].finalized_checkpoint.epoch)
|
|
|
|
|
|
|
|
validator_statuses.process_attestations(state[], cache)
|
|
|
|
let
|
|
|
|
total_balance = validator_statuses.total_balances.current_epoch
|
|
|
|
total_balance_sqrt = integer_squareroot(total_balance)
|
|
|
|
|
|
|
|
var
|
|
|
|
sourceDeltas2 = Deltas.init(state[].validators.len)
|
|
|
|
targetDeltas2 = Deltas.init(state[].validators.len)
|
|
|
|
headDeltas2 = Deltas.init(state[].validators.len)
|
|
|
|
inclusionDelayDeltas2 = Deltas.init(state[].validators.len)
|
|
|
|
inactivityPenaltyDeltas2 = Deltas.init(state[].validators.len)
|
|
|
|
|
|
|
|
for index, validator in validator_statuses.statuses.mpairs():
|
|
|
|
if not is_eligible_validator(validator):
|
|
|
|
continue
|
|
|
|
|
|
|
|
let
|
|
|
|
base_reward = get_base_reward_sqrt(
|
|
|
|
state[], index.ValidatorIndex, total_balance_sqrt)
|
|
|
|
|
|
|
|
sourceDeltas2.add(index, get_source_delta(
|
|
|
|
validator, base_reward, validator_statuses.total_balances, finality_delay))
|
|
|
|
targetDeltas2.add(index, get_target_delta(
|
|
|
|
validator, base_reward, validator_statuses.total_balances, finality_delay))
|
|
|
|
headDeltas2.add(index, get_head_delta(
|
|
|
|
validator, base_reward, validator_statuses.total_balances, finality_delay))
|
|
|
|
|
|
|
|
let
|
|
|
|
(inclusion_delay_delta, proposer_delta) =
|
|
|
|
get_inclusion_delay_delta(validator, base_reward)
|
|
|
|
inclusionDelayDeltas2.add(index, inclusion_delay_delta)
|
|
|
|
|
|
|
|
inactivityPenaltyDeltas2.add(index, get_inactivity_penalty_delta(
|
|
|
|
validator, base_reward, finality_delay))
|
|
|
|
|
|
|
|
if proposer_delta.isSome:
|
|
|
|
let proposer_index = proposer_delta.get()[0]
|
|
|
|
inclusionDelayDeltas2.add(proposer_index.int, proposer_delta.get()[1])
|
improve slot processing speeds (#1670)
about 40% better slot processing times (with LTO enabled) - these don't
do BLS but are used
heavily during replay (state transition = slot + block transition)
tests using a recent medalla state and advancing it 1000 slots:
```
./ncli slots --preState2:state-302271-3c1dbf19-c1f944bf.ssz --slot:1000
--postState2:xx.ssz
```
pre:
```
All time are ms
Average, StdDev, Min, Max, Samples,
Test
Validation is turned off meaning that no BLS operations are performed
39.236, 0.000, 39.236, 39.236, 1,
Load state from file
0.049, 0.002, 0.046, 0.063, 968,
Apply slot
256.504, 81.008, 213.471, 591.902, 32,
Apply epoch slot
28.597, 0.000, 28.597, 28.597, 1,
Save state to file
```
cast:
```
All time are ms
Average, StdDev, Min, Max, Samples,
Test
Validation is turned off meaning that no BLS operations are performed
37.079, 0.000, 37.079, 37.079, 1,
Load state from file
0.042, 0.002, 0.040, 0.090, 968,
Apply slot
215.552, 68.763, 180.155, 500.103, 32,
Apply epoch slot
25.106, 0.000, 25.106, 25.106, 1,
Save state to file
```
cast+rewards:
```
All time are ms
Average, StdDev, Min, Max, Samples,
Test
Validation is turned off meaning that no BLS operations are performed
40.049, 0.000, 40.049, 40.049, 1,
Load state from file
0.048, 0.001, 0.045, 0.060, 968,
Apply slot
164.981, 76.273, 142.099, 477.868, 32,
Apply epoch slot
28.498, 0.000, 28.498, 28.498, 1,
Save state to file
```
cast+rewards+shr
```
All time are ms
Average, StdDev, Min, Max, Samples,
Test
Validation is turned off meaning that no BLS operations are performed
12.898, 0.000, 12.898, 12.898, 1,
Load state from file
0.039, 0.002, 0.038, 0.054, 968,
Apply slot
139.971, 68.797, 120.088, 428.844, 32,
Apply epoch slot
24.761, 0.000, 24.761, 24.761, 1,
Save state to file
```
2020-09-16 20:59:33 +00:00
|
|
|
|
2020-08-17 01:09:27 +00:00
|
|
|
check:
|
2020-10-22 11:08:46 +00:00
|
|
|
sourceDeltas.rewards.asSeq == sourceDeltas2.rewards.asSeq
|
|
|
|
sourceDeltas.penalties.asSeq == sourceDeltas2.penalties.asSeq
|
|
|
|
|
|
|
|
targetDeltas.rewards.asSeq == targetDeltas2.rewards.asSeq
|
|
|
|
targetDeltas.penalties.asSeq == targetDeltas2.penalties.asSeq
|
|
|
|
|
|
|
|
headDeltas.rewards.asSeq == headDeltas2.rewards.asSeq
|
|
|
|
headDeltas.penalties.asSeq == headDeltas2.penalties.asSeq
|
|
|
|
|
|
|
|
inclusionDelayDeltas.rewards.asSeq == inclusionDelayDeltas2.rewards.asSeq
|
|
|
|
inclusionDelayDeltas.penalties.asSeq == inclusionDelayDeltas2.penalties.asSeq
|
|
|
|
|
|
|
|
inactivityPenaltyDeltas.rewards.asSeq == inactivityPenaltyDeltas2.rewards.asSeq
|
|
|
|
inactivityPenaltyDeltas.penalties.asSeq == inactivityPenaltyDeltas2.penalties.asSeq
|
|
|
|
|
2020-08-17 01:09:27 +00:00
|
|
|
|
|
|
|
`testImpl _ rewards _ identifier`()
|
|
|
|
|
|
|
|
suiteReport "Official - Rewards " & preset():
|
2020-09-21 15:58:35 +00:00
|
|
|
for rewardsDir in [RewardsDirBasic, RewardsDirLeak, RewardsDirRandom]:
|
|
|
|
for kind, path in walkDir(rewardsDir, true):
|
|
|
|
runTest(rewardsDir, path)
|