2019-06-28 13:44:44 +00:00
|
|
|
# beacon_chain
|
2021-02-14 19:31:01 +00:00
|
|
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
2019-06-28 13:44:44 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * 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).
|
2019-06-28 13:44:44 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
|
|
|
# State transition - epoch processing, as described in
|
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
|
|
|
|
#
|
2020-06-09 09:42:53 +00:00
|
|
|
# The entry point is `process_epoch`, which is at the bottom of this file.
|
2019-06-28 13:44:44 +00:00
|
|
|
#
|
2020-11-04 21:52:47 +00:00
|
|
|
# General notes about the code:
|
2019-06-28 13:44:44 +00:00
|
|
|
# * Weird styling - the sections taken from the spec use python styling while
|
|
|
|
# the others use NEP-1 - helps grepping identifiers in spec
|
2020-11-04 21:52:47 +00:00
|
|
|
# * When updating the code, add TODO sections to mark where there are clear
|
|
|
|
# improvements to be made - other than that, keep things similar to spec unless
|
|
|
|
# motivated by security or performance considerations
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-04-22 05:53:02 +00:00
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
2019-11-12 05:35:52 +00:00
|
|
|
import
|
2020-10-22 11:08:46 +00:00
|
|
|
std/[math, sequtils, tables, algorithm],
|
2020-11-27 22:16:13 +00:00
|
|
|
stew/[bitops2], chronicles,
|
2020-10-22 11:08:46 +00:00
|
|
|
../extras,
|
|
|
|
../ssz/merkleization,
|
|
|
|
./beaconstate, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
|
2019-12-20 16:14:43 +00:00
|
|
|
../../nbench/bench_lab
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2019-09-23 13:48:25 +00:00
|
|
|
# Logging utilities
|
|
|
|
# --------------------------------------------------------
|
|
|
|
|
|
|
|
logScope: topics = "consens"
|
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
type
|
|
|
|
# Caches for computing justificiation, rewards and penalties - based on
|
|
|
|
# implementation in Lighthouse:
|
|
|
|
# https://github.com/sigp/lighthouse/blob/master/consensus/state_processing/src/per_epoch_processing/validator_statuses.rs
|
|
|
|
Delta* = object
|
|
|
|
rewards*: Gwei
|
|
|
|
penalties*: Gwei
|
|
|
|
|
|
|
|
InclusionInfo = object
|
|
|
|
# The distance between the attestation slot and the slot that attestation
|
|
|
|
# was included in block.
|
|
|
|
delay: uint64
|
|
|
|
# The index of the proposer at the slot where the attestation was included.
|
|
|
|
proposer_index: uint64
|
|
|
|
|
|
|
|
ValidatorStatus = object
|
|
|
|
# True if the validator has been slashed, ever.
|
|
|
|
is_slashed: bool
|
|
|
|
# True if the validator can withdraw in the current epoch.
|
|
|
|
is_withdrawable_in_current_epoch: bool
|
|
|
|
# True if the validator was active in the state's _current_ epoch.
|
|
|
|
is_active_in_current_epoch: bool
|
|
|
|
# True if the validator was active in the state's _previous_ epoch.
|
|
|
|
is_active_in_previous_epoch: bool
|
|
|
|
# The validator's effective balance in the _current_ epoch.
|
|
|
|
current_epoch_effective_balance: uint64
|
|
|
|
|
|
|
|
# True if the validator had an attestation included in the _current_ epoch.
|
|
|
|
is_current_epoch_attester: bool
|
|
|
|
# True if the validator's beacon block root attestation for the first slot
|
|
|
|
# of the _current_ epoch matches the block root known to the state.
|
|
|
|
is_current_epoch_target_attester: bool
|
|
|
|
# True if the validator had an attestation included in the _previous_ epoch.
|
|
|
|
is_previous_epoch_attester: Option[InclusionInfo]
|
|
|
|
# Set if the validator's beacon block root attestation for the first slot of
|
|
|
|
# the _previous_ epoch matches the block root known to the state.
|
|
|
|
# Information used to reward the block producer of this validators
|
|
|
|
# earliest-included attestation.
|
|
|
|
is_previous_epoch_target_attester: bool
|
|
|
|
# True if the validator's beacon block root attestation in the _previous_
|
|
|
|
# epoch at the attestation's slot (`attestation_data.slot`) matches the
|
|
|
|
# block root known to the state.
|
|
|
|
is_previous_epoch_head_attester: bool
|
|
|
|
|
|
|
|
inclusion_info: Option[InclusionInfo]
|
|
|
|
|
|
|
|
# Total rewards and penalties for this validator
|
|
|
|
delta: Delta
|
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_total_balance
|
2020-10-22 11:08:46 +00:00
|
|
|
TotalBalances = object
|
|
|
|
# The total effective balance of all active validators during the _current_
|
|
|
|
# epoch.
|
|
|
|
current_epoch_raw: Gwei
|
|
|
|
# The total effective balance of all active validators during the _previous_
|
|
|
|
# epoch.
|
|
|
|
previous_epoch_raw: Gwei
|
|
|
|
# The total effective balance of all validators who attested during the
|
|
|
|
# _current_ epoch.
|
|
|
|
current_epoch_attesters_raw: Gwei
|
|
|
|
# The total effective balance of all validators who attested during the
|
|
|
|
# _current_ epoch and agreed with the state about the beacon block at the
|
|
|
|
# first slot of the _current_ epoch.
|
|
|
|
current_epoch_target_attesters_raw: Gwei
|
|
|
|
# The total effective balance of all validators who attested during the
|
|
|
|
# _previous_ epoch.
|
|
|
|
previous_epoch_attesters_raw: Gwei
|
|
|
|
# The total effective balance of all validators who attested during the
|
|
|
|
# _previous_ epoch and agreed with the state about the beacon block at the
|
|
|
|
# first slot of the _previous_ epoch.
|
|
|
|
previous_epoch_target_attesters_raw: Gwei
|
|
|
|
# The total effective balance of all validators who attested during the
|
|
|
|
# _previous_ epoch and agreed with the state about the beacon block at the
|
|
|
|
# time of attestation.
|
|
|
|
previous_epoch_head_attesters_raw: Gwei
|
|
|
|
|
|
|
|
ValidatorStatuses* = object
|
|
|
|
statuses*: seq[ValidatorStatus]
|
|
|
|
total_balances*: TotalBalances
|
|
|
|
|
|
|
|
# Accessors that implement the max condition in `get_total_balance`:
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_total_balance
|
2020-10-22 11:08:46 +00:00
|
|
|
template current_epoch*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.current_epoch_raw)
|
|
|
|
template previous_epoch*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.previous_epoch_raw)
|
|
|
|
template current_epoch_attesters*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.current_epoch_attesters_raw)
|
|
|
|
template current_epoch_target_attesters*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.current_epoch_target_attesters_raw)
|
|
|
|
template previous_epoch_attesters*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.previous_epoch_attesters_raw)
|
|
|
|
template previous_epoch_target_attesters*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.previous_epoch_target_attesters_raw)
|
|
|
|
template previous_epoch_head_attesters*(v: TotalBalances): Gwei =
|
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, v.previous_epoch_head_attesters_raw)
|
|
|
|
|
|
|
|
func init*(T: type ValidatorStatuses, state: BeaconState): T =
|
|
|
|
result.statuses = newSeq[ValidatorStatus](state.validators.len)
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
for i in 0..<state.validators.len:
|
|
|
|
let v = unsafeAddr state.validators[i]
|
|
|
|
result.statuses[i].is_slashed = v[].slashed
|
2020-10-22 11:08:46 +00:00
|
|
|
result.statuses[i].is_withdrawable_in_current_epoch =
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
state.get_current_epoch() >= v[].withdrawable_epoch
|
|
|
|
result.statuses[i].current_epoch_effective_balance = v[].effective_balance
|
2020-10-22 11:08:46 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
if v[].is_active_validator(state.get_current_epoch()):
|
2020-10-22 11:08:46 +00:00
|
|
|
result.statuses[i].is_active_in_current_epoch = true
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
result.total_balances.current_epoch_raw += v[].effective_balance
|
2020-10-22 11:08:46 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
if v[].is_active_validator(state.get_previous_epoch()):
|
2020-10-22 11:08:46 +00:00
|
|
|
result.statuses[i].is_active_in_previous_epoch = true
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
result.total_balances.previous_epoch_raw += v[].effective_balance
|
2020-10-22 11:08:46 +00:00
|
|
|
|
|
|
|
func add(a: var Delta, b: Delta) =
|
|
|
|
a.rewards += b.rewards
|
|
|
|
a.penalties += b.penalties
|
|
|
|
|
|
|
|
func process_attestation(
|
|
|
|
self: var ValidatorStatuses, state: BeaconState, a: PendingAttestation,
|
|
|
|
cache: var StateCache) =
|
|
|
|
# Collect information about the attestation
|
|
|
|
var
|
|
|
|
is_current_epoch_attester, is_current_epoch_target_attester: bool
|
|
|
|
is_previous_epoch_target_attester: bool
|
|
|
|
is_previous_epoch_head_attester: bool
|
|
|
|
is_previous_epoch_attester: Option[InclusionInfo]
|
|
|
|
|
|
|
|
if a.data.target.epoch == state.get_current_epoch():
|
|
|
|
is_current_epoch_attester = true
|
|
|
|
|
|
|
|
if a.data.target.root == get_block_root(state, state.get_current_epoch()):
|
|
|
|
is_current_epoch_target_attester = true;
|
|
|
|
|
|
|
|
elif a.data.target.epoch == state.get_previous_epoch():
|
|
|
|
is_previous_epoch_attester = some(InclusionInfo(
|
|
|
|
delay: a.inclusion_delay,
|
|
|
|
proposer_index: a.proposer_index,
|
|
|
|
))
|
|
|
|
|
|
|
|
if a.data.target.root == get_block_root(state, state.get_previous_epoch()):
|
|
|
|
is_previous_epoch_target_attester = true;
|
|
|
|
|
|
|
|
if a.data.beacon_block_root == get_block_root_at_slot(state, a.data.slot):
|
|
|
|
is_previous_epoch_head_attester = true
|
|
|
|
|
|
|
|
# Update the cache for all participants
|
|
|
|
for validator_index in get_attesting_indices(
|
|
|
|
state, a.data, a.aggregation_bits, cache):
|
|
|
|
template v(): untyped = self.statuses[validator_index]
|
|
|
|
if is_current_epoch_attester:
|
|
|
|
v.is_current_epoch_attester = true
|
|
|
|
|
|
|
|
if is_current_epoch_target_attester:
|
|
|
|
v.is_current_epoch_target_attester = true
|
|
|
|
|
|
|
|
if is_previous_epoch_attester.isSome:
|
|
|
|
if v.is_previous_epoch_attester.isSome:
|
|
|
|
if is_previous_epoch_attester.get().delay <
|
|
|
|
v.is_previous_epoch_attester.get().delay:
|
|
|
|
v.is_previous_epoch_attester = is_previous_epoch_attester
|
|
|
|
else:
|
|
|
|
v.is_previous_epoch_attester = is_previous_epoch_attester
|
|
|
|
|
|
|
|
if is_previous_epoch_target_attester:
|
|
|
|
v.is_previous_epoch_target_attester = true
|
|
|
|
|
|
|
|
if is_previous_epoch_head_attester:
|
|
|
|
v.is_previous_epoch_head_attester = true
|
|
|
|
|
|
|
|
func process_attestations*(
|
|
|
|
self: var ValidatorStatuses, state: BeaconState, cache: var StateCache) =
|
|
|
|
# Walk state attestations and update the status information
|
|
|
|
for a in state.previous_epoch_attestations:
|
|
|
|
process_attestation(self, state, a, cache)
|
|
|
|
for a in state.current_epoch_attestations:
|
|
|
|
process_attestation(self, state, a, cache)
|
|
|
|
|
|
|
|
for idx, v in self.statuses:
|
|
|
|
if v.is_slashed:
|
|
|
|
continue
|
|
|
|
|
|
|
|
let validator_balance = state.validators[idx].effective_balance
|
|
|
|
|
|
|
|
if v.is_current_epoch_attester:
|
|
|
|
self.total_balances.current_epoch_attesters_raw += validator_balance
|
|
|
|
|
|
|
|
if v.is_current_epoch_target_attester:
|
|
|
|
self.total_balances.current_epoch_target_attesters_raw += validator_balance
|
|
|
|
|
|
|
|
if v.is_previous_epoch_attester.isSome():
|
|
|
|
self.total_balances.previous_epoch_attesters_raw += validator_balance
|
|
|
|
|
|
|
|
if v.is_previous_epoch_target_attester:
|
|
|
|
self.total_balances.previous_epoch_target_attesters_raw += validator_balance
|
|
|
|
|
|
|
|
if v.is_previous_epoch_head_attester:
|
|
|
|
self.total_balances.previous_epoch_head_attesters_raw += validator_balance
|
|
|
|
|
|
|
|
func is_eligible_validator*(validator: ValidatorStatus): bool =
|
|
|
|
validator.is_active_in_previous_epoch or
|
|
|
|
(validator.is_slashed and (not validator.is_withdrawable_in_current_epoch))
|
|
|
|
|
2019-09-23 13:48:25 +00:00
|
|
|
# Spec
|
|
|
|
# --------------------------------------------------------
|
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_total_active_balance
|
2020-06-03 05:42:08 +00:00
|
|
|
func get_total_active_balance*(state: BeaconState, cache: var StateCache): Gwei =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return the combined effective balance of the active validators.
|
2020-03-30 23:40:24 +00:00
|
|
|
# Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei
|
|
|
|
# minimum to avoid divisions by zero.
|
2020-06-03 05:42:08 +00:00
|
|
|
|
2020-09-08 08:54:55 +00:00
|
|
|
let epoch = state.get_current_epoch()
|
2020-06-03 05:42:08 +00:00
|
|
|
|
2020-07-27 16:04:44 +00:00
|
|
|
get_total_balance(
|
|
|
|
state, cache.get_shuffled_active_validator_indices(state, epoch))
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#justification-and-finalization
|
2020-05-09 12:43:15 +00:00
|
|
|
proc process_justification_and_finalization*(state: var BeaconState,
|
2020-10-22 11:08:46 +00:00
|
|
|
total_balances: TotalBalances, updateFlags: UpdateFlags = {}) {.nbench.} =
|
2020-09-24 17:04:10 +00:00
|
|
|
# Initial FFG checkpoint values have a `0x00` stub for `root`.
|
|
|
|
# Skip FFG updates in the first two epochs to avoid corner cases that might
|
|
|
|
# result in modifying this stub.
|
2019-06-28 13:44:44 +00:00
|
|
|
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
|
|
|
|
return
|
|
|
|
|
|
|
|
let
|
|
|
|
previous_epoch = get_previous_epoch(state)
|
|
|
|
current_epoch = get_current_epoch(state)
|
2019-07-16 07:34:11 +00:00
|
|
|
old_previous_justified_checkpoint = state.previous_justified_checkpoint
|
|
|
|
old_current_justified_checkpoint = state.current_justified_checkpoint
|
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
# Process justifications
|
2019-07-16 07:34:11 +00:00
|
|
|
state.previous_justified_checkpoint = state.current_justified_checkpoint
|
|
|
|
|
|
|
|
## Spec:
|
|
|
|
## state.justification_bits[1:] = state.justification_bits[:-1]
|
|
|
|
## state.justification_bits[0] = 0b0
|
2020-11-12 19:24:07 +00:00
|
|
|
|
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#constants
|
2019-09-27 16:40:33 +00:00
|
|
|
const JUSTIFICATION_BITS_LENGTH = 4
|
2020-11-12 19:24:07 +00:00
|
|
|
|
2019-09-27 16:40:33 +00:00
|
|
|
state.justification_bits = (state.justification_bits shl 1) and
|
|
|
|
cast[uint8]((2^JUSTIFICATION_BITS_LENGTH) - 1)
|
2019-07-16 07:34:11 +00:00
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
let total_active_balance = total_balances.current_epoch
|
|
|
|
if total_balances.previous_epoch_target_attesters * 3 >=
|
|
|
|
total_active_balance * 2:
|
2019-07-16 07:34:11 +00:00
|
|
|
state.current_justified_checkpoint =
|
|
|
|
Checkpoint(epoch: previous_epoch,
|
|
|
|
root: get_block_root(state, previous_epoch))
|
2019-12-20 13:25:33 +00:00
|
|
|
state.justification_bits.setBit 1
|
2019-07-16 07:34:11 +00:00
|
|
|
|
2020-08-19 08:03:50 +00:00
|
|
|
trace "Justified with previous epoch",
|
2019-09-23 13:48:25 +00:00
|
|
|
current_epoch = current_epoch,
|
2020-07-16 13:16:51 +00:00
|
|
|
checkpoint = shortLog(state.current_justified_checkpoint)
|
2020-10-22 11:08:46 +00:00
|
|
|
elif verifyFinalization in updateFlags:
|
|
|
|
warn "Low attestation participation in previous epoch",
|
|
|
|
total_balances, epoch = get_current_epoch(state)
|
2019-09-23 13:48:25 +00:00
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
if total_balances.current_epoch_target_attesters * 3 >=
|
|
|
|
total_active_balance * 2:
|
2019-07-16 07:34:11 +00:00
|
|
|
state.current_justified_checkpoint =
|
|
|
|
Checkpoint(epoch: current_epoch,
|
|
|
|
root: get_block_root(state, current_epoch))
|
2019-12-20 13:25:33 +00:00
|
|
|
state.justification_bits.setBit 0
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-19 08:03:50 +00:00
|
|
|
trace "Justified with current epoch",
|
2019-09-23 13:48:25 +00:00
|
|
|
current_epoch = current_epoch,
|
2020-07-16 13:16:51 +00:00
|
|
|
checkpoint = shortLog(state.current_justified_checkpoint)
|
2019-09-23 13:48:25 +00:00
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
# Process finalizations
|
2019-07-01 09:42:37 +00:00
|
|
|
let bitfield = state.justification_bits
|
2019-06-28 13:44:44 +00:00
|
|
|
|
|
|
|
## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th
|
|
|
|
## as source
|
2019-07-03 07:35:05 +00:00
|
|
|
if (bitfield and 0b1110) == 0b1110 and
|
|
|
|
old_previous_justified_checkpoint.epoch + 3 == current_epoch:
|
2019-07-16 07:34:11 +00:00
|
|
|
state.finalized_checkpoint = old_previous_justified_checkpoint
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-19 08:03:50 +00:00
|
|
|
trace "Finalized with rule 234",
|
2019-09-23 13:48:25 +00:00
|
|
|
current_epoch = current_epoch,
|
2020-07-16 13:16:51 +00:00
|
|
|
checkpoint = shortLog(state.finalized_checkpoint)
|
2019-09-23 13:48:25 +00:00
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as
|
|
|
|
## source
|
2019-07-03 07:35:05 +00:00
|
|
|
if (bitfield and 0b110) == 0b110 and
|
|
|
|
old_previous_justified_checkpoint.epoch + 2 == current_epoch:
|
2019-07-16 07:34:11 +00:00
|
|
|
state.finalized_checkpoint = old_previous_justified_checkpoint
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-19 08:03:50 +00:00
|
|
|
trace "Finalized with rule 23",
|
2019-09-23 13:48:25 +00:00
|
|
|
current_epoch = current_epoch,
|
2020-07-16 13:16:51 +00:00
|
|
|
checkpoint = shortLog(state.finalized_checkpoint)
|
2019-09-23 13:48:25 +00:00
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as
|
|
|
|
## source
|
2019-07-03 07:35:05 +00:00
|
|
|
if (bitfield and 0b111) == 0b111 and
|
|
|
|
old_current_justified_checkpoint.epoch + 2 == current_epoch:
|
2019-07-16 07:34:11 +00:00
|
|
|
state.finalized_checkpoint = old_current_justified_checkpoint
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-19 08:03:50 +00:00
|
|
|
trace "Finalized with rule 123",
|
2019-09-23 13:48:25 +00:00
|
|
|
current_epoch = current_epoch,
|
2020-07-16 13:16:51 +00:00
|
|
|
checkpoint = shortLog(state.finalized_checkpoint)
|
2019-09-23 13:48:25 +00:00
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as
|
|
|
|
## source
|
2019-07-03 07:35:05 +00:00
|
|
|
if (bitfield and 0b11) == 0b11 and
|
|
|
|
old_current_justified_checkpoint.epoch + 1 == current_epoch:
|
2019-07-16 07:34:11 +00:00
|
|
|
state.finalized_checkpoint = old_current_justified_checkpoint
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-19 08:03:50 +00:00
|
|
|
trace "Finalized with rule 12",
|
2019-09-23 13:48:25 +00:00
|
|
|
current_epoch = current_epoch,
|
2020-07-16 13:16:51 +00:00
|
|
|
checkpoint = shortLog(state.finalized_checkpoint)
|
2019-09-23 13:48:25 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#helpers
|
2020-10-22 11:08:46 +00:00
|
|
|
func get_base_reward_sqrt*(state: BeaconState, index: ValidatorIndex,
|
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
|
|
|
total_balance_sqrt: auto): Gwei =
|
2019-11-15 22:37:39 +00:00
|
|
|
# Spec function recalculates total_balance every time, which creates an
|
|
|
|
# O(n^2) situation.
|
|
|
|
let effective_balance = state.validators[index].effective_balance
|
2019-06-28 13:44:44 +00:00
|
|
|
effective_balance * BASE_REWARD_FACTOR div
|
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
|
|
|
total_balance_sqrt div BASE_REWARDS_PER_EPOCH
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
func get_proposer_reward(base_reward: Gwei): Gwei =
|
2020-07-07 16:52:12 +00:00
|
|
|
# Spec version recalculates get_total_active_balance(state) quadratically
|
2020-10-22 11:08:46 +00:00
|
|
|
base_reward div PROPOSER_REWARD_QUOTIENT
|
|
|
|
|
|
|
|
func is_in_inactivity_leak(finality_delay: uint64): bool =
|
|
|
|
finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY
|
2020-06-08 18:41:50 +00:00
|
|
|
|
|
|
|
func get_finality_delay(state: BeaconState): uint64 =
|
|
|
|
get_previous_epoch(state) - state.finalized_checkpoint.epoch
|
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
func get_attestation_component_delta(is_unslashed_attester: bool,
|
|
|
|
attesting_balance: Gwei,
|
|
|
|
total_balance: Gwei,
|
|
|
|
base_reward: uint64,
|
|
|
|
finality_delay: uint64): Delta =
|
2020-06-08 18:41:50 +00:00
|
|
|
# Helper with shared logic for use by get source, target, and head deltas
|
|
|
|
# functions
|
2020-10-22 11:08:46 +00:00
|
|
|
if is_unslashed_attester:
|
|
|
|
if is_in_inactivity_leak(finality_delay):
|
|
|
|
# Since full base reward will be canceled out by inactivity penalty deltas,
|
|
|
|
# optimal participation receives full base reward compensation here.
|
|
|
|
Delta(rewards: base_reward)
|
2020-06-08 18:41:50 +00:00
|
|
|
else:
|
2020-10-22 11:08:46 +00:00
|
|
|
let reward_numerator =
|
|
|
|
base_reward * (attesting_balance div EFFECTIVE_BALANCE_INCREMENT)
|
|
|
|
Delta(rewards:
|
|
|
|
reward_numerator div (total_balance div EFFECTIVE_BALANCE_INCREMENT))
|
|
|
|
else:
|
|
|
|
Delta(penalties: base_reward)
|
2020-06-08 18:41:50 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#components-of-attestation-deltas
|
2020-10-22 11:08:46 +00:00
|
|
|
func get_source_delta*(validator: ValidatorStatus,
|
|
|
|
base_reward: uint64,
|
|
|
|
total_balances: TotalBalances,
|
|
|
|
finality_delay: uint64): Delta =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return attester micro-rewards/penalties for source-vote for each validator.
|
2020-10-22 11:08:46 +00:00
|
|
|
get_attestation_component_delta(
|
|
|
|
validator.is_previous_epoch_attester.isSome() and (not validator.is_slashed),
|
|
|
|
total_balances.previous_epoch_attesters,
|
|
|
|
total_balances.current_epoch,
|
|
|
|
base_reward,
|
|
|
|
finality_delay)
|
|
|
|
|
|
|
|
func get_target_delta*(validator: ValidatorStatus,
|
|
|
|
base_reward: uint64,
|
|
|
|
total_balances: TotalBalances,
|
|
|
|
finality_delay: uint64): Delta =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return attester micro-rewards/penalties for target-vote for each validator.
|
2020-10-22 11:08:46 +00:00
|
|
|
get_attestation_component_delta(
|
|
|
|
validator.is_previous_epoch_target_attester and (not validator.is_slashed),
|
|
|
|
total_balances.previous_epoch_target_attesters,
|
|
|
|
total_balances.current_epoch,
|
|
|
|
base_reward,
|
|
|
|
finality_delay)
|
|
|
|
|
|
|
|
func get_head_delta*(validator: ValidatorStatus,
|
|
|
|
base_reward: uint64,
|
|
|
|
total_balances: TotalBalances,
|
|
|
|
finality_delay: uint64): Delta =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return attester micro-rewards/penalties for head-vote for each validator.
|
2020-10-22 11:08:46 +00:00
|
|
|
get_attestation_component_delta(
|
|
|
|
validator.is_previous_epoch_head_attester and (not validator.is_slashed),
|
|
|
|
total_balances.previous_epoch_head_attesters,
|
|
|
|
total_balances.current_epoch,
|
|
|
|
base_reward,
|
|
|
|
finality_delay)
|
|
|
|
|
|
|
|
func get_inclusion_delay_delta*(validator: ValidatorStatus,
|
|
|
|
base_reward: uint64):
|
|
|
|
(Delta, Option[(uint64, Delta)]) =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return proposer and inclusion delay micro-rewards/penalties for each validator.
|
2020-10-22 11:08:46 +00:00
|
|
|
if validator.is_previous_epoch_attester.isSome() and (not validator.is_slashed):
|
|
|
|
let
|
|
|
|
inclusion_info = validator.is_previous_epoch_attester.get()
|
|
|
|
proposer_reward = get_proposer_reward(base_reward)
|
|
|
|
proposer_delta = Delta(rewards: proposer_reward)
|
2020-07-10 09:24:04 +00:00
|
|
|
|
2020-06-08 18:41:50 +00:00
|
|
|
let
|
2020-10-22 11:08:46 +00:00
|
|
|
max_attester_reward = base_reward - proposer_reward
|
|
|
|
delta = Delta(rewards: max_attester_reward div inclusion_info.delay)
|
|
|
|
proposer_index = inclusion_info.proposer_index;
|
|
|
|
return (delta, some((proposer_index, proposer_delta)))
|
|
|
|
|
|
|
|
func get_inactivity_penalty_delta*(validator: ValidatorStatus,
|
|
|
|
base_reward: Gwei,
|
|
|
|
finality_delay: uint64): Delta =
|
|
|
|
## Return inactivity reward/penalty deltas for each validator.
|
|
|
|
var delta: Delta
|
|
|
|
|
|
|
|
if is_in_inactivity_leak(finality_delay):
|
|
|
|
# If validator is performing optimally this cancels all rewards for a neutral balance
|
|
|
|
delta.penalties +=
|
|
|
|
BASE_REWARDS_PER_EPOCH * base_reward - get_proposer_reward(base_reward)
|
|
|
|
|
|
|
|
# Additionally, all validators whose FFG target didn't match are penalized extra
|
|
|
|
# This condition is equivalent to this condition from the spec:
|
|
|
|
# `index not in get_unslashed_attesting_indices(state, matching_target_attestations)`
|
|
|
|
if validator.is_slashed or (not validator.is_previous_epoch_target_attester):
|
|
|
|
delta.penalties +=
|
|
|
|
validator.current_epoch_effective_balance * finality_delay div
|
|
|
|
INACTIVITY_PENALTY_QUOTIENT
|
|
|
|
|
|
|
|
delta
|
2020-06-08 18:41:50 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_attestation_deltas
|
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
|
|
|
func get_attestation_deltas(
|
2020-10-22 11:08:46 +00:00
|
|
|
state: BeaconState, validator_statuses: var ValidatorStatuses) =
|
|
|
|
## Update validator_statuses with attestation reward/penalty deltas for each validator.
|
|
|
|
|
2020-06-29 18:08:58 +00:00
|
|
|
let
|
2020-10-22 11:08:46 +00:00
|
|
|
finality_delay = get_finality_delay(state)
|
|
|
|
total_balance = validator_statuses.total_balances.current_epoch
|
|
|
|
total_balance_sqrt = integer_squareroot(total_balance)
|
|
|
|
# Filter out ineligible validators. All sub-functions of the spec do this
|
|
|
|
# except for `get_inclusion_delay_deltas`. It's safe to do so here because
|
|
|
|
# any validator that is in the unslashed indices of the matching source
|
|
|
|
# attestations is active, and therefore eligible.
|
|
|
|
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)
|
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-10-22 11:08:46 +00:00
|
|
|
let
|
|
|
|
source_delta = get_source_delta(
|
|
|
|
validator, base_reward, validator_statuses.total_balances, finality_delay)
|
|
|
|
target_delta = get_target_delta(
|
|
|
|
validator, base_reward, validator_statuses.total_balances, finality_delay)
|
|
|
|
head_delta = get_head_delta(
|
|
|
|
validator, base_reward, validator_statuses.total_balances, finality_delay)
|
|
|
|
(inclusion_delay_delta, proposer_delta) =
|
|
|
|
get_inclusion_delay_delta(validator, base_reward)
|
|
|
|
inactivity_delta = get_inactivity_penalty_delta(
|
|
|
|
validator, base_reward, finality_delay)
|
|
|
|
|
|
|
|
validator.delta.add source_delta
|
|
|
|
validator.delta.add target_delta
|
|
|
|
validator.delta.add head_delta
|
|
|
|
validator.delta.add inclusion_delay_delta
|
|
|
|
validator.delta.add inactivity_delta
|
|
|
|
|
|
|
|
if proposer_delta.isSome:
|
|
|
|
let proposer_index = proposer_delta.get()[0]
|
|
|
|
if proposer_index < validator_statuses.statuses.lenu64:
|
|
|
|
validator_statuses.statuses[proposer_index].delta.add(
|
|
|
|
proposer_delta.get()[1])
|
2020-06-08 18:41:50 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#process_rewards_and_penalties
|
2019-06-28 13:44:44 +00:00
|
|
|
func process_rewards_and_penalties(
|
2020-10-22 11:08:46 +00:00
|
|
|
state: var BeaconState, validator_statuses: var ValidatorStatuses) {.nbench.} =
|
2020-09-24 17:04:10 +00:00
|
|
|
# No rewards are applied at the end of `GENESIS_EPOCH` because rewards are
|
|
|
|
# for work done in the previous epoch
|
2020-10-22 11:08:46 +00:00
|
|
|
doAssert validator_statuses.statuses.len == state.validators.len
|
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
if get_current_epoch(state) == GENESIS_EPOCH:
|
|
|
|
return
|
|
|
|
|
2020-10-22 11:08:46 +00:00
|
|
|
get_attestation_deltas(state, validator_statuses)
|
2019-10-01 14:40:41 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
# Here almost all balances are updated (assuming most validators are active) -
|
|
|
|
# clearing the cache becomes a bottleneck if done item by item because of the
|
|
|
|
# recursive nature of cache clearing - instead, we clear the whole cache then
|
|
|
|
# update the raw list directly
|
|
|
|
state.balances.clearCache()
|
2020-10-22 11:08:46 +00:00
|
|
|
for idx, v in validator_statuses.statuses:
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
increase_balance(state.balances.asSeq()[idx], v.delta.rewards)
|
|
|
|
decrease_balance(state.balances.asSeq()[idx], v.delta.penalties)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#slashings
|
2020-10-22 11:08:46 +00:00
|
|
|
func process_slashings*(state: var BeaconState, total_balance: Gwei) {.nbench.}=
|
2019-06-28 13:44:44 +00:00
|
|
|
let
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
epoch = get_current_epoch(state)
|
2020-10-08 18:00:07 +00:00
|
|
|
adjusted_total_slashing_balance =
|
|
|
|
min(sum(state.slashings) * PROPORTIONAL_SLASHING_MULTIPLIER, total_balance)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
for index in 0..<state.validators.len:
|
|
|
|
let validator = unsafeAddr state.validators.asSeq()[index]
|
|
|
|
if validator[].slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR div 2 ==
|
|
|
|
validator[].withdrawable_epoch:
|
2019-09-03 03:12:09 +00:00
|
|
|
let increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty
|
|
|
|
# numerator to avoid uint64 overflow
|
|
|
|
let penalty_numerator =
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
validator[].effective_balance div increment *
|
2020-10-08 18:00:07 +00:00
|
|
|
adjusted_total_slashing_balance
|
2019-09-03 03:12:09 +00:00
|
|
|
let penalty = penalty_numerator div total_balance * increment
|
2019-06-28 13:44:44 +00:00
|
|
|
decrease_balance(state, index.ValidatorIndex, penalty)
|
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#eth1-data-votes-updates
|
|
|
|
func process_eth1_data_reset(state: var BeaconState) {.nbench.} =
|
|
|
|
let next_epoch = get_current_epoch(state) + 1
|
2019-06-28 13:44:44 +00:00
|
|
|
|
|
|
|
# Reset eth1 data votes
|
2020-03-14 21:54:45 +00:00
|
|
|
if next_epoch mod EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
|
2020-05-27 11:36:02 +00:00
|
|
|
state.eth1_data_votes = default(type state.eth1_data_votes)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#effective-balances-updates
|
|
|
|
func process_effective_balance_updates(state: var BeaconState) {.nbench.} =
|
2019-06-28 13:44:44 +00:00
|
|
|
# Update effective balances with hysteresis
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
for index in 0..<state.validators.len:
|
|
|
|
let balance = state.balances.asSeq()[index]
|
2020-03-14 21:54:45 +00:00
|
|
|
const
|
|
|
|
HYSTERESIS_INCREMENT =
|
|
|
|
EFFECTIVE_BALANCE_INCREMENT div HYSTERESIS_QUOTIENT
|
|
|
|
DOWNWARD_THRESHOLD =
|
|
|
|
HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
|
|
|
|
UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
let effective_balance = state.validators.asSeq()[index].effective_balance
|
|
|
|
if balance + DOWNWARD_THRESHOLD < effective_balance or
|
|
|
|
effective_balance + UPWARD_THRESHOLD < balance:
|
2019-07-01 09:13:14 +00:00
|
|
|
state.validators[index].effective_balance =
|
2019-06-28 13:44:44 +00:00
|
|
|
min(
|
|
|
|
balance - balance mod EFFECTIVE_BALANCE_INCREMENT,
|
|
|
|
MAX_EFFECTIVE_BALANCE)
|
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#slashings-balances-updates
|
|
|
|
func process_slashings_reset(state: var BeaconState) {.nbench.} =
|
|
|
|
let next_epoch = get_current_epoch(state) + 1
|
|
|
|
|
2019-07-10 12:23:02 +00:00
|
|
|
# Reset slashings
|
2020-06-12 16:43:20 +00:00
|
|
|
state.slashings[int(next_epoch mod EPOCHS_PER_SLASHINGS_VECTOR)] = 0.Gwei
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#randao-mixes-updates
|
|
|
|
func process_randao_mixes_reset(state: var BeaconState) {.nbench.} =
|
|
|
|
let
|
|
|
|
current_epoch = get_current_epoch(state)
|
|
|
|
next_epoch = current_epoch + 1
|
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
# Set randao mix
|
2019-09-04 13:57:18 +00:00
|
|
|
state.randao_mixes[next_epoch mod EPOCHS_PER_HISTORICAL_VECTOR] =
|
2019-06-28 13:44:44 +00:00
|
|
|
get_randao_mix(state, current_epoch)
|
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#historical-roots-updates
|
|
|
|
func process_historical_roots_update(state: var BeaconState) {.nbench.} =
|
2019-06-28 13:44:44 +00:00
|
|
|
# Set historical root accumulator
|
2021-02-14 19:31:01 +00:00
|
|
|
let next_epoch = get_current_epoch(state) + 1
|
|
|
|
|
2020-07-13 14:44:58 +00:00
|
|
|
if next_epoch mod (SLOTS_PER_HISTORICAL_ROOT div SLOTS_PER_EPOCH) == 0:
|
2020-04-23 11:39:38 +00:00
|
|
|
# Equivalent to hash_tree_root(foo: HistoricalBatch), but without using
|
|
|
|
# significant additional stack or heap.
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#historicalbatch
|
2020-10-08 19:02:05 +00:00
|
|
|
# In response to https://github.com/status-im/nimbus-eth2/issues/921
|
2020-04-23 11:39:38 +00:00
|
|
|
state.historical_roots.add hash_tree_root(
|
|
|
|
[hash_tree_root(state.block_roots), hash_tree_root(state.state_roots)])
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#participation-records-rotation
|
|
|
|
func process_participation_record_updates(state: var BeaconState) {.nbench.} =
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
# Rotate current/previous epoch attestations - using swap avoids copying all
|
|
|
|
# elements using a slow genericSeqAssign
|
|
|
|
state.previous_epoch_attestations.clear()
|
|
|
|
swap(state.previous_epoch_attestations, state.current_epoch_attestations)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-14 19:31:01 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#final-updates
|
|
|
|
func process_final_updates*(state: var BeaconState) {.nbench.} =
|
|
|
|
# This function's a wrapper over the HF1 split/refactored HF1 version. TODO
|
|
|
|
# remove once test vectors become available for each HF1 function.
|
|
|
|
process_eth1_data_reset(state)
|
|
|
|
process_effective_balance_updates(state)
|
|
|
|
process_slashings_reset(state)
|
|
|
|
process_randao_mixes_reset(state)
|
|
|
|
process_historical_roots_update(state)
|
|
|
|
process_participation_record_updates(state)
|
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#epoch-processing
|
2020-06-01 07:44:50 +00:00
|
|
|
proc process_epoch*(state: var BeaconState, updateFlags: UpdateFlags,
|
2020-10-22 11:08:46 +00:00
|
|
|
cache: var StateCache) {.nbench.} =
|
2020-05-11 06:25:49 +00:00
|
|
|
let currentEpoch = get_current_epoch(state)
|
2019-08-19 16:41:13 +00:00
|
|
|
trace "process_epoch",
|
2020-05-11 06:25:49 +00:00
|
|
|
current_epoch = currentEpoch
|
2020-10-22 11:08:46 +00:00
|
|
|
var validator_statuses = ValidatorStatuses.init(state)
|
|
|
|
validator_statuses.process_attestations(state, cache)
|
2019-08-14 08:56:32 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#justification-and-finalization
|
2020-10-22 11:08:46 +00:00
|
|
|
process_justification_and_finalization(
|
|
|
|
state, validator_statuses.total_balances, updateFlags)
|
2020-05-09 12:43:15 +00:00
|
|
|
|
|
|
|
# state.slot hasn't been incremented yet.
|
2020-07-28 17:35:32 +00:00
|
|
|
if verifyFinalization in updateFlags and currentEpoch >= 2:
|
|
|
|
doAssert state.current_justified_checkpoint.epoch + 2 >= currentEpoch
|
|
|
|
|
2020-05-11 06:25:49 +00:00
|
|
|
if verifyFinalization in updateFlags and currentEpoch >= 3:
|
2020-05-09 12:43:15 +00:00
|
|
|
# Rule 2/3/4 finalization results in the most pessimal case. The other
|
|
|
|
# three finalization rules finalize more quickly as long as the any of
|
|
|
|
# the finalization rules triggered.
|
2020-05-11 06:25:49 +00:00
|
|
|
doAssert state.finalized_checkpoint.epoch + 3 >= currentEpoch
|
2019-08-14 08:56:32 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#rewards-and-penalties-1
|
2020-10-22 11:08:46 +00:00
|
|
|
process_rewards_and_penalties(state, validator_statuses)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#registry-updates
|
2020-10-22 11:08:46 +00:00
|
|
|
process_registry_updates(state, cache)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#slashings
|
2020-10-22 11:08:46 +00:00
|
|
|
process_slashings(state, validator_statuses.total_balances.current_epoch)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-11-09 14:18:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#final-updates
|
2019-06-28 13:44:44 +00:00
|
|
|
process_final_updates(state)
|