2018-11-28 19:49:03 +00:00
|
|
|
# beacon_chain
|
2023-01-06 21:01:10 +00:00
|
|
|
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
2018-11-28 19:49:03 +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).
|
2018-11-28 19:49:03 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2023-01-20 14:14:37 +00:00
|
|
|
{.push raises: [].}
|
2020-04-22 05:53:02 +00:00
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
import
|
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
|
|
|
stew/assign2,
|
2020-11-27 22:16:13 +00:00
|
|
|
json_serialization/std/sets,
|
|
|
|
chronicles,
|
2021-08-18 18:57:58 +00:00
|
|
|
../extras,
|
2022-01-06 11:25:35 +00:00
|
|
|
./datatypes/[phase0, altair, bellatrix],
|
2021-12-03 14:46:56 +00:00
|
|
|
"."/[eth2_merkleization, forks, signatures, validator]
|
2018-11-28 19:49:03 +00:00
|
|
|
|
2022-12-08 16:21:53 +00:00
|
|
|
from std/algorithm import fill
|
|
|
|
from std/sequtils import anyIt, mapIt
|
|
|
|
|
2022-10-27 06:29:24 +00:00
|
|
|
from ./datatypes/capella import BeaconState, ExecutionPayloadHeader, Withdrawal
|
|
|
|
|
2023-02-23 02:10:07 +00:00
|
|
|
export extras, forks, validator, chronicles
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-06-30 16:12:54 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#increase_balance
|
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
|
|
|
func increase_balance*(balance: var Gwei, delta: Gwei) =
|
|
|
|
balance += delta
|
|
|
|
|
2019-05-09 12:27:37 +00:00
|
|
|
func increase_balance*(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: var ForkyBeaconState, index: ValidatorIndex, delta: Gwei) =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Increase the validator balance at index ``index`` by ``delta``.
|
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 delta != 0: # avoid dirtying the balance cache if not needed
|
2022-05-30 13:30:42 +00:00
|
|
|
increase_balance(state.balances.mitem(index), delta)
|
2019-03-08 17:44:31 +00:00
|
|
|
|
2023-07-05 16:02:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#decrease_balance
|
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
|
|
|
func decrease_balance*(balance: var Gwei, delta: Gwei) =
|
|
|
|
balance =
|
|
|
|
if delta > balance:
|
|
|
|
0'u64
|
|
|
|
else:
|
|
|
|
balance - delta
|
|
|
|
|
2019-05-09 12:27:37 +00:00
|
|
|
func decrease_balance*(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: var ForkyBeaconState, index: ValidatorIndex, delta: Gwei) =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Decrease the validator balance at index ``index`` by ``delta``, with
|
|
|
|
## underflow protection.
|
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 delta != 0: # avoid dirtying the balance cache if not needed
|
2022-05-30 13:30:42 +00:00
|
|
|
decrease_balance(state.balances.mitem(index), delta)
|
2019-05-09 12:27:37 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#deposits
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/beacon-chain.md#modified-apply_deposit
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
func get_validator_from_deposit*(deposit: DepositData):
|
2020-07-27 10:59:57 +00:00
|
|
|
Validator =
|
|
|
|
let
|
2020-11-14 21:43:27 +00:00
|
|
|
amount = deposit.amount
|
2020-07-27 10:59:57 +00:00
|
|
|
effective_balance = min(
|
|
|
|
amount - amount mod EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
|
|
|
|
|
|
|
Validator(
|
2020-11-14 21:43:27 +00:00
|
|
|
pubkey: deposit.pubkey,
|
|
|
|
withdrawal_credentials: deposit.withdrawal_credentials,
|
2020-07-27 10:59:57 +00:00
|
|
|
activation_eligibility_epoch: FAR_FUTURE_EPOCH,
|
|
|
|
activation_epoch: FAR_FUTURE_EPOCH,
|
|
|
|
exit_epoch: FAR_FUTURE_EPOCH,
|
|
|
|
withdrawable_epoch: FAR_FUTURE_EPOCH,
|
|
|
|
effective_balance: effective_balance
|
|
|
|
)
|
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#compute_activation_exit_epoch
|
2021-10-12 11:36:52 +00:00
|
|
|
func compute_activation_exit_epoch*(epoch: Epoch): Epoch =
|
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
|
|
|
## Return the epoch during which validator activations and exits initiated in
|
|
|
|
## ``epoch`` take effect.
|
initial 0.9.0 spec sync (#509)
* rename compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* remove some unnecessary imports; remove some crosslink-related code and tests; complete renaming of compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* rm more transfer-related code and tests; rm more unnecessary strutils imports
* rm remaining unused imports
* remove useless get_empty_per_epoch_cache(...)/compute_start_slot_of_epoch(...) calls
* rename compute_start_slot_of_epoch(...) to compute_start_slot_at_epoch(...)
* rename ACTIVATION_EXIT_DELAY to MAX_SEED_LOOKAHEAD
* update domain types to 0.9.0
* mark AttesterSlashing, IndexedAttestation, AttestationDataAndCustodyBit, DepositData, BeaconBlockHeader, Fork, integer_squareroot(...), and process_voluntary_exit(...) as 0.9.0
* mark increase_balance(...), decrease_balance(...), get_block_root(...), CheckPoint, Deposit, PendingAttestation, HistoricalBatch, is_active_validator(...), and is_slashable_attestation_data(...) as 0.9.0
* mark compute_activation_exit_epoch(...), bls_verify(...), Validator, get_active_validator_indices(...), get_current_epoch(...), get_total_active_balance(...), and get_previous_epoch(...) as 0.9.0
* mark get_block_root_at_slot(...), ProposerSlashing, get_domain(...), VoluntaryExit, mainnet preset Gwei values, minimal preset max operations, process_block_header(...), and is_slashable_validator(...) as 0.9.0
* mark makeWithdrawalCredentials(...), get_validator_churn_limit(...), get_total_balance(...), is_valid_indexed_attestation(...), bls_aggregate_pubkeys(...), initial genesis value/constants, Attestation, get_randao_mix(...), mainnet preset max operations per block constants, minimal preset Gwei values and time parameters, process_eth1_data(...), get_shuffled_seq(...), compute_committee(...), and process_slots(...) as 0.9.0; partially update get_indexed_attestation(...) to 0.9.0 by removing crosslink refs and associated tests
* mark initiate_validator_exit(...), process_registry_updates(...), BeaconBlock, Eth1Data, compute_domain(...), process_randao(...), process_attester_slashing(...), get_base_reward(...), and process_slot(...) as 0.9.0
2019-10-30 19:41:19 +00:00
|
|
|
epoch + 1 + MAX_SEED_LOOKAHEAD
|
2019-01-29 03:22:22 +00:00
|
|
|
|
2023-07-05 16:02:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#get_validator_churn_limit
|
2021-10-12 11:36:52 +00:00
|
|
|
func get_validator_churn_limit*(
|
2021-11-05 07:34:34 +00:00
|
|
|
cfg: RuntimeConfig, state: ForkyBeaconState, cache: var StateCache):
|
2021-05-28 15:25:58 +00:00
|
|
|
uint64 =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return the validator churn limit for the current epoch.
|
2020-07-23 17:01:07 +00:00
|
|
|
max(
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
cfg.MIN_PER_EPOCH_CHURN_LIMIT,
|
2020-07-23 17:01:07 +00:00
|
|
|
count_active_validators(
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
state, state.get_current_epoch(), cache) div cfg.CHURN_LIMIT_QUOTIENT)
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#initiate_validator_exit
|
2022-05-25 13:49:29 +00:00
|
|
|
func initiate_validator_exit*(
|
|
|
|
cfg: RuntimeConfig, state: var ForkyBeaconState,
|
|
|
|
index: ValidatorIndex, cache: var StateCache): Result[void, cstring] =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Initiate the exit of the validator with index ``index``.
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
2022-05-30 13:30:42 +00:00
|
|
|
if state.validators.item(index).exit_epoch != FAR_FUTURE_EPOCH:
|
2022-05-25 13:49:29 +00:00
|
|
|
return ok() # Before touching cache
|
2021-11-12 22:29:28 +00:00
|
|
|
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
# Return if validator already initiated exit
|
2022-05-30 13:30:42 +00:00
|
|
|
let validator = addr state.validators.mitem(index)
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
2020-11-02 17:34:23 +00:00
|
|
|
trace "Validator exiting",
|
|
|
|
index = index,
|
|
|
|
num_validators = state.validators.len,
|
|
|
|
current_epoch = get_current_epoch(state),
|
|
|
|
validator_slashed = validator.slashed,
|
|
|
|
validator_withdrawable_epoch = validator.withdrawable_epoch,
|
|
|
|
validator_exit_epoch = validator.exit_epoch,
|
|
|
|
validator_effective_balance = validator.effective_balance
|
|
|
|
|
|
|
|
var exit_queue_epoch = compute_activation_exit_epoch(get_current_epoch(state))
|
|
|
|
# Compute max exit 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
|
|
|
for idx in 0..<state.validators.len:
|
2022-05-30 13:30:42 +00:00
|
|
|
let exit_epoch = state.validators.item(idx).exit_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
|
|
|
if exit_epoch != FAR_FUTURE_EPOCH and exit_epoch > exit_queue_epoch:
|
|
|
|
exit_queue_epoch = exit_epoch
|
2020-11-02 17:34:23 +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
|
|
|
var
|
|
|
|
exit_queue_churn: int
|
|
|
|
for idx in 0..<state.validators.len:
|
2022-05-30 13:30:42 +00:00
|
|
|
if state.validators.item(idx).exit_epoch == exit_queue_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
|
|
|
exit_queue_churn += 1
|
2020-11-02 17:34:23 +00:00
|
|
|
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
if exit_queue_churn.uint64 >= get_validator_churn_limit(cfg, state, cache):
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
exit_queue_epoch += 1
|
|
|
|
|
|
|
|
# Set validator exit epoch and withdrawable epoch
|
|
|
|
validator.exit_epoch = exit_queue_epoch
|
2022-05-25 13:49:29 +00:00
|
|
|
|
|
|
|
if validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY <
|
|
|
|
validator.exit_epoch:
|
|
|
|
return err("initiate_validator_exit: exit_epoch overflowed")
|
|
|
|
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
validator.withdrawable_epoch =
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
2018-12-13 16:00:55 +00:00
|
|
|
|
2022-05-25 13:49:29 +00:00
|
|
|
ok()
|
|
|
|
|
2023-02-22 13:10:00 +00:00
|
|
|
from ./datatypes/deneb import BeaconState
|
2022-12-06 12:40:13 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#slash_validator
|
2023-06-30 16:12:54 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#modified-slash_validator
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/bellatrix/beacon-chain.md#modified-slash_validator
|
2022-02-17 11:53:55 +00:00
|
|
|
func get_slashing_penalty*(state: ForkyBeaconState,
|
2021-12-29 02:50:49 +00:00
|
|
|
validator_effective_balance: Gwei): Gwei =
|
|
|
|
# TODO Consider whether this is better than splitting the functions apart; in
|
|
|
|
# each case, tradeoffs. Here, it's just changing a couple of constants.
|
|
|
|
when state is phase0.BeaconState:
|
|
|
|
validator_effective_balance div MIN_SLASHING_PENALTY_QUOTIENT
|
|
|
|
elif state is altair.BeaconState:
|
|
|
|
validator_effective_balance div MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR
|
2022-12-06 12:40:13 +00:00
|
|
|
elif state is bellatrix.BeaconState or state is capella.BeaconState or
|
2023-02-22 13:10:00 +00:00
|
|
|
state is deneb.BeaconState:
|
2022-10-27 06:29:24 +00:00
|
|
|
validator_effective_balance div MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX
|
2021-12-29 02:50:49 +00:00
|
|
|
else:
|
2022-01-17 12:58:33 +00:00
|
|
|
{.fatal: "invalid BeaconState type".}
|
2021-12-29 02:50:49 +00:00
|
|
|
|
2023-06-30 16:12:54 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#slash_validator
|
2023-07-05 16:02:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#modified-slash_validator
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/bellatrix/beacon-chain.md#modified-slash_validator
|
2022-01-17 12:58:33 +00:00
|
|
|
func get_whistleblower_reward*(validator_effective_balance: Gwei): Gwei =
|
2021-12-29 02:50:49 +00:00
|
|
|
validator_effective_balance div WHISTLEBLOWER_REWARD_QUOTIENT
|
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#slash_validator
|
2023-04-21 18:52:43 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/beacon-chain.md#modified-slash_validator
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/beacon-chain.md#modified-slash_validator
|
2022-01-17 12:58:33 +00:00
|
|
|
func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): Gwei =
|
2021-12-29 02:50:49 +00:00
|
|
|
when state is phase0.BeaconState:
|
|
|
|
whistleblower_reward div PROPOSER_REWARD_QUOTIENT
|
2022-10-27 06:29:24 +00:00
|
|
|
elif state is altair.BeaconState or state is bellatrix.BeaconState or
|
2023-02-22 13:10:00 +00:00
|
|
|
state is capella.BeaconState or state is deneb.BeaconState:
|
2021-12-29 02:50:49 +00:00
|
|
|
whistleblower_reward * PROPOSER_WEIGHT div WEIGHT_DENOMINATOR
|
|
|
|
else:
|
2022-01-17 12:58:33 +00:00
|
|
|
{.fatal: "invalid BeaconState type".}
|
2021-12-29 02:50:49 +00:00
|
|
|
|
2023-06-30 16:12:54 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#slash_validator
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#modified-slash_validator
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/bellatrix/beacon-chain.md#modified-slash_validator
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
proc slash_validator*(
|
2021-11-05 07:34:34 +00:00
|
|
|
cfg: RuntimeConfig, state: var ForkyBeaconState,
|
2022-05-25 13:49:29 +00:00
|
|
|
slashed_index: ValidatorIndex, cache: var StateCache):
|
|
|
|
Result[void, cstring] =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Slash the validator with index ``index``.
|
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
|
|
|
let epoch = get_current_epoch(state)
|
2022-05-25 13:49:29 +00:00
|
|
|
? initiate_validator_exit(cfg, state, slashed_index, cache)
|
2022-05-30 13:30:42 +00:00
|
|
|
|
|
|
|
let validator = addr state.validators.mitem(slashed_index)
|
2019-11-25 08:22:16 +00:00
|
|
|
|
2020-11-02 17:34:23 +00:00
|
|
|
trace "slash_validator: ejecting validator via slashing (validator_leaving)",
|
2019-11-25 08:22:16 +00:00
|
|
|
index = slashed_index,
|
|
|
|
num_validators = state.validators.len,
|
|
|
|
current_epoch = get_current_epoch(state),
|
|
|
|
validator_slashed = validator.slashed,
|
|
|
|
validator_withdrawable_epoch = validator.withdrawable_epoch,
|
|
|
|
validator_exit_epoch = validator.exit_epoch,
|
|
|
|
validator_effective_balance = validator.effective_balance
|
|
|
|
|
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
|
|
|
validator.slashed = true
|
|
|
|
validator.withdrawable_epoch =
|
|
|
|
max(validator.withdrawable_epoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR)
|
2022-05-30 13:30:42 +00:00
|
|
|
state.slashings.mitem(int(epoch mod EPOCHS_PER_SLASHINGS_VECTOR)) +=
|
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
|
|
|
validator.effective_balance
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2021-12-29 02:50:49 +00:00
|
|
|
decrease_balance(state, slashed_index,
|
|
|
|
get_slashing_penalty(state, validator.effective_balance))
|
2019-02-20 20:35:27 +00:00
|
|
|
|
2019-12-04 10:49:59 +00:00
|
|
|
# The rest doesn't make sense without there being any proposer index, so skip
|
2023-01-11 12:29:21 +00:00
|
|
|
let proposer_index = get_beacon_proposer_index(state, cache).valueOr:
|
2019-12-04 10:49:59 +00:00
|
|
|
debug "No beacon proposer index and probably no active validators"
|
2022-05-25 13:49:29 +00:00
|
|
|
return ok()
|
2019-12-04 10:49:59 +00:00
|
|
|
|
2020-07-08 08:56:25 +00:00
|
|
|
# Apply proposer and whistleblower rewards
|
2019-01-29 03:22:22 +00:00
|
|
|
let
|
2019-06-12 07:48:49 +00:00
|
|
|
# Spec has whistleblower_index as optional param, but it's never used.
|
2023-01-11 12:29:21 +00:00
|
|
|
whistleblower_index = proposer_index
|
2021-12-29 02:50:49 +00:00
|
|
|
whistleblower_reward = get_whistleblower_reward(validator.effective_balance)
|
|
|
|
proposer_reward = get_proposer_reward(state, whistleblower_reward)
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
increase_balance(state, proposer_index, proposer_reward)
|
2019-09-10 22:03:06 +00:00
|
|
|
# TODO: evaluate if spec bug / underflow can be triggered
|
2021-05-28 15:25:58 +00:00
|
|
|
doAssert(whistleblower_reward >= proposer_reward, "Spec bug: underflow in slash_validator")
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
increase_balance(
|
2021-05-28 15:25:58 +00:00
|
|
|
state, whistleblower_index, whistleblower_reward - proposer_reward)
|
2019-01-16 13:39:34 +00:00
|
|
|
|
2022-05-25 13:49:29 +00:00
|
|
|
ok()
|
|
|
|
|
Implement split preset/config support (#2710)
* Implement split preset/config support
This is the initial bulk refactor to introduce runtime config values in
a number of places, somewhat replacing the existing mechanism of loading
network metadata.
It still needs more work, this is the initial refactor that introduces
runtime configuration in some of the places that need it.
The PR changes the way presets and constants work, to match the spec. In
particular, a "preset" now refers to the compile-time configuration
while a "cfg" or "RuntimeConfig" is the dynamic part.
A single binary can support either mainnet or minimal, but not both.
Support for other presets has been removed completely (can be readded,
in case there's need).
There's a number of outstanding tasks:
* `SECONDS_PER_SLOT` still needs fixing
* loading custom runtime configs needs redoing
* checking constants against YAML file
* yeerongpilly support
`build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG`
* load fork epoch from config
* fix fork digest sent in status
* nicer error string for request failures
* fix tools
* one more
* fixup
* fixup
* fixup
* use "standard" network definition folder in local testnet
Files are loaded from their standard locations, including genesis etc,
to conform to the format used in the `eth2-networks` repo.
* fix launch scripts, allow unknown config values
* fix base config of rest test
* cleanups
* bundle mainnet config using common loader
* fix spec links and names
* only include supported preset in binary
* drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
|
|
|
func genesis_time_from_eth1_timestamp*(cfg: RuntimeConfig, eth1_timestamp: uint64): uint64 =
|
|
|
|
eth1_timestamp + cfg.GENESIS_DELAY
|
2020-06-27 12:01:19 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#genesis-block
|
2021-11-18 12:02:43 +00:00
|
|
|
func get_initial_beacon_block*(state: phase0.HashedBeaconState):
|
2021-05-28 15:25:58 +00:00
|
|
|
phase0.TrustedSignedBeaconBlock =
|
2021-05-17 16:37:26 +00:00
|
|
|
# The genesis block is implicitly trusted
|
2021-05-28 15:25:58 +00:00
|
|
|
let message = phase0.TrustedBeaconBlock(
|
2021-11-18 12:02:43 +00:00
|
|
|
slot: state.data.slot,
|
|
|
|
state_root: state.root)
|
2020-09-22 20:42:42 +00:00
|
|
|
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
|
|
|
# initialized to default values.
|
2021-05-28 15:25:58 +00:00
|
|
|
phase0.TrustedSignedBeaconBlock(
|
|
|
|
message: message, root: hash_tree_root(message))
|
2019-09-08 18:27:09 +00:00
|
|
|
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/beacon-chain.md#initialize-state-for-pure-altair-testnets-and-test-vectors
|
2021-11-18 12:02:43 +00:00
|
|
|
func get_initial_beacon_block*(state: altair.HashedBeaconState):
|
2021-11-10 11:39:08 +00:00
|
|
|
altair.TrustedSignedBeaconBlock =
|
|
|
|
# The genesis block is implicitly trusted
|
|
|
|
let message = altair.TrustedBeaconBlock(
|
2021-11-18 12:02:43 +00:00
|
|
|
slot: state.data.slot,
|
|
|
|
state_root: state.root)
|
2021-11-10 11:39:08 +00:00
|
|
|
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
|
|
|
# initialized to default values.
|
|
|
|
altair.TrustedSignedBeaconBlock(
|
|
|
|
message: message, root: hash_tree_root(message))
|
|
|
|
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/beacon-chain.md#testing
|
2022-01-06 11:25:35 +00:00
|
|
|
func get_initial_beacon_block*(state: bellatrix.HashedBeaconState):
|
|
|
|
bellatrix.TrustedSignedBeaconBlock =
|
2021-11-10 11:39:08 +00:00
|
|
|
# The genesis block is implicitly trusted
|
2022-01-06 11:25:35 +00:00
|
|
|
let message = bellatrix.TrustedBeaconBlock(
|
2021-11-18 12:02:43 +00:00
|
|
|
slot: state.data.slot,
|
2021-12-23 14:58:54 +00:00
|
|
|
state_root: state.root)
|
2021-11-10 11:39:08 +00:00
|
|
|
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
|
|
|
# initialized to default values.
|
2022-01-06 11:25:35 +00:00
|
|
|
bellatrix.TrustedSignedBeaconBlock(
|
2021-11-10 11:39:08 +00:00
|
|
|
message: message, root: hash_tree_root(message))
|
|
|
|
|
2023-05-06 10:32:59 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#testing
|
|
|
|
func get_initial_beacon_block*(state: capella.HashedBeaconState):
|
|
|
|
capella.TrustedSignedBeaconBlock =
|
2022-12-07 16:47:23 +00:00
|
|
|
# The genesis block is implicitly trusted
|
2023-05-06 10:32:59 +00:00
|
|
|
let message = capella.TrustedBeaconBlock(
|
2022-12-07 16:47:23 +00:00
|
|
|
slot: state.data.slot,
|
|
|
|
state_root: state.root)
|
|
|
|
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
|
|
|
# initialized to default values.
|
2023-05-06 10:32:59 +00:00
|
|
|
capella.TrustedSignedBeaconBlock(
|
2022-12-07 16:47:23 +00:00
|
|
|
message: message, root: hash_tree_root(message))
|
|
|
|
|
2023-05-06 10:32:59 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#testing
|
|
|
|
func get_initial_beacon_block*(state: deneb.HashedBeaconState):
|
|
|
|
deneb.TrustedSignedBeaconBlock =
|
2022-11-02 16:23:30 +00:00
|
|
|
# The genesis block is implicitly trusted
|
2023-05-06 10:32:59 +00:00
|
|
|
let message = deneb.TrustedBeaconBlock(
|
2022-11-02 16:23:30 +00:00
|
|
|
slot: state.data.slot,
|
|
|
|
state_root: state.root)
|
|
|
|
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
|
|
|
# initialized to default values.
|
2023-05-06 10:32:59 +00:00
|
|
|
deneb.TrustedSignedBeaconBlock(
|
2022-11-02 16:23:30 +00:00
|
|
|
message: message, root: hash_tree_root(message))
|
|
|
|
|
2021-11-10 11:39:08 +00:00
|
|
|
func get_initial_beacon_block*(state: ForkedHashedBeaconState):
|
|
|
|
ForkedTrustedSignedBeaconBlock =
|
|
|
|
withState(state):
|
2022-08-26 14:14:18 +00:00
|
|
|
ForkedTrustedSignedBeaconBlock.init(get_initial_beacon_block(forkyState))
|
2021-11-10 11:39:08 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#get_block_root_at_slot
|
2021-11-05 07:34:34 +00:00
|
|
|
func get_block_root_at_slot*(state: ForkyBeaconState, slot: Slot): Eth2Digest =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return the block root at a recent ``slot``.
|
2019-02-13 10:26:32 +00:00
|
|
|
|
2020-09-02 16:16:25 +00:00
|
|
|
# Potential overflow/wrap shouldn't occur, as get_block_root_at_slot() called
|
|
|
|
# from internally controlled sources, but flag this explicitly, in case.
|
|
|
|
doAssert slot + SLOTS_PER_HISTORICAL_ROOT > slot
|
|
|
|
|
2019-03-16 19:52:37 +00:00
|
|
|
doAssert state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
|
2018-12-14 16:12:39 +00:00
|
|
|
doAssert slot < state.slot
|
2019-07-01 07:53:42 +00:00
|
|
|
state.block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
|
2018-11-29 05:23:40 +00:00
|
|
|
|
2022-07-06 10:33:02 +00:00
|
|
|
func get_block_root_at_slot*(
|
|
|
|
state: ForkedHashedBeaconState, slot: Slot): Eth2Digest =
|
2021-11-05 07:34:34 +00:00
|
|
|
## Return the block root at a recent ``slot``.
|
|
|
|
withState(state):
|
2022-08-26 14:14:18 +00:00
|
|
|
get_block_root_at_slot(forkyState.data, slot)
|
2021-11-05 07:34:34 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#get_block_root
|
2021-11-05 07:34:34 +00:00
|
|
|
func get_block_root*(state: ForkyBeaconState, epoch: Epoch): Eth2Digest =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Return the block root at the start of a recent ``epoch``.
|
2022-01-11 10:01:54 +00:00
|
|
|
get_block_root_at_slot(state, epoch.start_slot())
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
2022-07-06 10:33:02 +00:00
|
|
|
func get_block_root*(state: ForkedHashedBeaconState, epoch: Epoch): Eth2Digest =
|
|
|
|
## Return the block root at the start of a recent ``epoch``.
|
|
|
|
withState(state):
|
2022-08-26 14:14:18 +00:00
|
|
|
get_block_root(forkyState.data, epoch)
|
2022-07-06 10:33:02 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#get_total_balance
|
2021-08-25 14:43:00 +00:00
|
|
|
template get_total_balance(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: ForkyBeaconState, validator_indices: untyped): Gwei =
|
2020-03-30 11:31:44 +00:00
|
|
|
## Return the combined effective balance of the ``indices``.
|
|
|
|
## ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
2022-07-06 10:33:02 +00:00
|
|
|
## Math safe up to ~10B ETH, after which this overflows uint64.
|
2021-08-24 20:09:03 +00:00
|
|
|
var res = 0.Gwei
|
|
|
|
for validator_index in validator_indices:
|
2022-05-30 13:30:42 +00:00
|
|
|
res += state.validators[validator_index].effective_balance
|
2021-08-24 20:09:03 +00:00
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT, res)
|
2019-02-22 18:46:45 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue
|
2021-10-12 11:36:52 +00:00
|
|
|
func is_eligible_for_activation_queue*(validator: Validator): bool =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Check if ``validator`` is eligible to be placed into the activation queue.
|
2019-12-16 18:08:50 +00:00
|
|
|
validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and
|
|
|
|
validator.effective_balance == MAX_EFFECTIVE_BALANCE
|
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#is_eligible_for_activation
|
2022-07-06 10:33:02 +00:00
|
|
|
func is_eligible_for_activation*(
|
|
|
|
state: ForkyBeaconState, validator: Validator): bool =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Check if ``validator`` is eligible for activation.
|
2019-12-16 18:08:50 +00:00
|
|
|
|
|
|
|
# Placement in queue is finalized
|
|
|
|
validator.activation_eligibility_epoch <= state.finalized_checkpoint.epoch and
|
|
|
|
# Has not yet been activated
|
|
|
|
validator.activation_epoch == FAR_FUTURE_EPOCH
|
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#is_valid_indexed_attestation
|
2020-07-23 14:38:28 +00:00
|
|
|
proc is_valid_indexed_attestation*(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: ForkyBeaconState, indexed_attestation: SomeIndexedAttestation,
|
2020-08-13 13:47:06 +00:00
|
|
|
flags: UpdateFlags): Result[void, cstring] =
|
2020-09-08 08:54:55 +00:00
|
|
|
## Check if ``indexed_attestation`` is not empty, has sorted and unique
|
|
|
|
## indices and has a valid aggregate signature.
|
2020-06-22 10:37:47 +00:00
|
|
|
|
|
|
|
template is_sorted_and_unique(s: untyped): bool =
|
2020-08-13 13:47:06 +00:00
|
|
|
var res = true
|
2020-06-22 10:37:47 +00:00
|
|
|
for i in 1 ..< s.len:
|
|
|
|
if s[i - 1].uint64 >= s[i].uint64:
|
2020-08-13 13:47:06 +00:00
|
|
|
res = false
|
|
|
|
break
|
|
|
|
res
|
2020-06-22 10:37:47 +00:00
|
|
|
|
2020-08-13 13:47:06 +00:00
|
|
|
if len(indexed_attestation.attesting_indices) == 0:
|
|
|
|
return err("indexed_attestation: no attesting indices")
|
2020-06-22 10:37:47 +00:00
|
|
|
|
|
|
|
# Not from spec, but this function gets used in front-line roles, not just
|
|
|
|
# behind firewall.
|
2020-07-26 18:55:48 +00:00
|
|
|
let num_validators = state.validators.lenu64
|
2020-06-22 10:37:47 +00:00
|
|
|
if anyIt(indexed_attestation.attesting_indices, it >= num_validators):
|
2020-08-13 13:47:06 +00:00
|
|
|
return err("indexed attestation: not all indices valid validators")
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2020-08-13 13:47:06 +00:00
|
|
|
if not is_sorted_and_unique(indexed_attestation.attesting_indices):
|
|
|
|
return err("indexed attestation: indices not sorted and unique")
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2019-06-14 07:50:14 +00:00
|
|
|
# Verify aggregate signature
|
2022-04-14 15:39:37 +00:00
|
|
|
if not (skipBlsValidation in flags or indexed_attestation.signature is TrustedSig):
|
2020-08-13 13:47:06 +00:00
|
|
|
let pubkeys = mapIt(
|
|
|
|
indexed_attestation.attesting_indices, state.validators[it].pubkey)
|
2020-06-16 05:45:04 +00:00
|
|
|
if not verify_attestation_signature(
|
|
|
|
state.fork, state.genesis_validators_root, indexed_attestation.data,
|
|
|
|
pubkeys, indexed_attestation.signature):
|
2020-08-13 13:47:06 +00:00
|
|
|
return err("indexed attestation: signature verification failure")
|
2019-11-21 09:57:59 +00:00
|
|
|
|
2020-08-13 13:47:06 +00:00
|
|
|
ok()
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2023-06-30 16:12:54 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#get_attesting_indices
|
2021-11-05 07:34:34 +00:00
|
|
|
func get_attesting_indices*(state: ForkyBeaconState,
|
2021-06-11 17:51:46 +00:00
|
|
|
data: AttestationData,
|
|
|
|
bits: CommitteeValidatorsBits,
|
|
|
|
cache: var StateCache): seq[ValidatorIndex] =
|
2022-01-08 23:28:49 +00:00
|
|
|
## Return the set of attesting indices corresponding to ``data`` and ``bits``
|
|
|
|
## or nothing if `data` is invalid
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
var res: seq[ValidatorIndex]
|
|
|
|
# Can't be an iterator due to https://github.com/nim-lang/Nim/issues/18188
|
2022-01-08 23:28:49 +00:00
|
|
|
let committee_index = CommitteeIndex.init(data.index)
|
|
|
|
if committee_index.isErr() or bits.lenu64 != get_beacon_committee_len(
|
|
|
|
state, data.slot, committee_index.get(), cache):
|
|
|
|
trace "get_attesting_indices: invalid attestation data"
|
2020-10-22 10:53:33 +00:00
|
|
|
else:
|
2022-01-08 23:28:49 +00:00
|
|
|
for index_in_committee, validator_index in get_beacon_committee(
|
2022-05-10 10:03:40 +00:00
|
|
|
state, data.slot, committee_index.get(), cache):
|
2022-01-08 23:28:49 +00:00
|
|
|
if bits[index_in_committee]:
|
|
|
|
res.add validator_index
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2021-06-11 17:51:46 +00:00
|
|
|
res
|
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
func get_attesting_indices*(state: ForkedHashedBeaconState;
|
2021-11-05 07:34:34 +00:00
|
|
|
data: AttestationData;
|
|
|
|
bits: CommitteeValidatorsBits;
|
|
|
|
cache: var StateCache): seq[ValidatorIndex] =
|
|
|
|
# TODO when https://github.com/nim-lang/Nim/issues/18188 fixed, use an
|
|
|
|
# iterator
|
|
|
|
|
|
|
|
var idxBuf: seq[ValidatorIndex]
|
|
|
|
withState(state):
|
2022-08-26 14:14:18 +00:00
|
|
|
for vidx in forkyState.data.get_attesting_indices(data, bits, cache):
|
2021-11-05 07:34:34 +00:00
|
|
|
idxBuf.add vidx
|
|
|
|
idxBuf
|
|
|
|
|
2021-04-14 14:43:29 +00:00
|
|
|
proc is_valid_indexed_attestation*(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
2021-04-14 14:43:29 +00:00
|
|
|
cache: var StateCache): Result[void, cstring] =
|
|
|
|
# This is a variation on `is_valid_indexed_attestation` that works directly
|
|
|
|
# with an attestation instead of first constructing an `IndexedAttestation`
|
|
|
|
# and then validating it - for the purpose of validating the signature, the
|
|
|
|
# order doesn't matter and we can proceed straight to validating the
|
|
|
|
# signature instead
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2021-04-14 14:43:29 +00:00
|
|
|
let sigs = attestation.aggregation_bits.countOnes()
|
|
|
|
if sigs == 0:
|
|
|
|
return err("is_valid_indexed_attestation: no attesting indices")
|
|
|
|
|
|
|
|
# Verify aggregate signature
|
2022-04-14 15:39:37 +00:00
|
|
|
if not (skipBlsValidation in flags or attestation.signature is TrustedSig):
|
2021-04-14 14:43:29 +00:00
|
|
|
var
|
|
|
|
pubkeys = newSeqOfCap[ValidatorPubKey](sigs)
|
|
|
|
for index in get_attesting_indices(
|
|
|
|
state, attestation.data, attestation.aggregation_bits, cache):
|
|
|
|
pubkeys.add(state.validators[index].pubkey)
|
|
|
|
|
|
|
|
if not verify_attestation_signature(
|
|
|
|
state.fork, state.genesis_validators_root, attestation.data,
|
|
|
|
pubkeys, attestation.signature):
|
|
|
|
return err("indexed attestation: signature verification failure")
|
|
|
|
|
|
|
|
ok()
|
2020-06-25 10:23:10 +00:00
|
|
|
|
2020-06-10 06:58:12 +00:00
|
|
|
# Attestation validation
|
|
|
|
# ------------------------------------------------------------------------------------------
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#attestations
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
|
2020-06-10 06:58:12 +00:00
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
func check_attestation_slot_target*(data: AttestationData): Result[Slot, cstring] =
|
2022-01-11 10:01:54 +00:00
|
|
|
if not (data.target.epoch == epoch(data.slot)):
|
2020-07-27 16:04:44 +00:00
|
|
|
return err("Target epoch doesn't match attestation slot")
|
2020-06-10 06:58:12 +00:00
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
ok(data.slot)
|
2020-06-10 06:58:12 +00:00
|
|
|
|
2020-10-20 08:54:11 +00:00
|
|
|
func check_attestation_target_epoch(
|
2022-01-08 23:28:49 +00:00
|
|
|
data: AttestationData, current_epoch: Epoch): Result[Epoch, cstring] =
|
2020-07-27 16:04:44 +00:00
|
|
|
if not (data.target.epoch == get_previous_epoch(current_epoch) or
|
|
|
|
data.target.epoch == current_epoch):
|
|
|
|
return err("Target epoch not current or previous epoch")
|
2020-06-10 06:58:12 +00:00
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
ok(data.target.epoch)
|
2020-06-10 06:58:12 +00:00
|
|
|
|
2023-06-24 12:27:15 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#attestations
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#modified-process_attestation
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/beacon-chain.md#modified-process_attestation
|
|
|
|
func check_attestation_inclusion(
|
|
|
|
consensusFork: static ConsensusFork, attestation_slot: Slot,
|
|
|
|
current_slot: Slot): Result[void, cstring] =
|
2020-09-02 16:16:25 +00:00
|
|
|
# Check for overflow
|
|
|
|
static:
|
|
|
|
doAssert SLOTS_PER_EPOCH >= MIN_ATTESTATION_INCLUSION_DELAY
|
2022-01-08 23:28:49 +00:00
|
|
|
if attestation_slot + SLOTS_PER_EPOCH <= attestation_slot:
|
2020-09-02 16:16:25 +00:00
|
|
|
return err("attestation data.slot overflow, malicious?")
|
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
if not (attestation_slot + MIN_ATTESTATION_INCLUSION_DELAY <= current_slot):
|
2020-07-27 16:04:44 +00:00
|
|
|
return err("Attestation too new")
|
2020-06-10 06:58:12 +00:00
|
|
|
|
2023-06-24 12:27:15 +00:00
|
|
|
when consensusFork < ConsensusFork.Deneb:
|
|
|
|
if not (current_slot <= attestation_slot + SLOTS_PER_EPOCH):
|
|
|
|
return err("Attestation too old")
|
2020-07-27 16:04:44 +00:00
|
|
|
|
|
|
|
ok()
|
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
func check_attestation_index*(
|
|
|
|
index, committees_per_slot: uint64):
|
|
|
|
Result[CommitteeIndex, cstring] =
|
|
|
|
CommitteeIndex.init(index, committees_per_slot)
|
2020-07-27 16:04:44 +00:00
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
func check_attestation_index*(
|
|
|
|
data: AttestationData, committees_per_slot: uint64):
|
|
|
|
Result[CommitteeIndex, cstring] =
|
|
|
|
check_attestation_index(data.index, committees_per_slot)
|
2020-07-27 16:04:44 +00:00
|
|
|
|
2023-06-24 12:27:15 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices
|
2022-10-27 06:29:24 +00:00
|
|
|
func get_attestation_participation_flag_indices(
|
2023-06-24 12:27:15 +00:00
|
|
|
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState,
|
2022-10-27 06:29:24 +00:00
|
|
|
data: AttestationData, inclusion_delay: uint64): seq[int] =
|
2021-05-28 15:25:58 +00:00
|
|
|
## Return the flag indices that are satisfied by an attestation.
|
|
|
|
let justified_checkpoint =
|
|
|
|
if data.target.epoch == get_current_epoch(state):
|
|
|
|
state.current_justified_checkpoint
|
|
|
|
else:
|
|
|
|
state.previous_justified_checkpoint
|
|
|
|
|
|
|
|
# Matching roots
|
|
|
|
let
|
|
|
|
is_matching_source = data.source == justified_checkpoint
|
2023-06-24 12:27:15 +00:00
|
|
|
is_matching_target =
|
|
|
|
is_matching_source and
|
|
|
|
data.target.root == get_block_root(state, data.target.epoch)
|
|
|
|
is_matching_head =
|
|
|
|
is_matching_target and
|
|
|
|
data.beacon_block_root == get_block_root_at_slot(state, data.slot)
|
|
|
|
|
|
|
|
# Checked by check_attestation()
|
2021-05-28 15:25:58 +00:00
|
|
|
doAssert is_matching_source
|
|
|
|
|
|
|
|
var participation_flag_indices: seq[int]
|
|
|
|
if is_matching_source and inclusion_delay <= integer_squareroot(SLOTS_PER_EPOCH):
|
|
|
|
participation_flag_indices.add(TIMELY_SOURCE_FLAG_INDEX)
|
|
|
|
if is_matching_target and inclusion_delay <= SLOTS_PER_EPOCH:
|
|
|
|
participation_flag_indices.add(TIMELY_TARGET_FLAG_INDEX)
|
|
|
|
if is_matching_head and inclusion_delay == MIN_ATTESTATION_INCLUSION_DELAY:
|
|
|
|
participation_flag_indices.add(TIMELY_HEAD_FLAG_INDEX)
|
|
|
|
|
|
|
|
participation_flag_indices
|
|
|
|
|
2023-06-24 12:27:15 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/deneb/beacon-chain.md#modified-get_attestation_participation_flag_indices
|
|
|
|
func get_attestation_participation_flag_indices(
|
|
|
|
state: deneb.BeaconState,
|
|
|
|
data: AttestationData, inclusion_delay: uint64): seq[int] =
|
|
|
|
## Return the flag indices that are satisfied by an attestation.
|
|
|
|
let justified_checkpoint =
|
|
|
|
if data.target.epoch == get_current_epoch(state):
|
|
|
|
state.current_justified_checkpoint
|
|
|
|
else:
|
|
|
|
state.previous_justified_checkpoint
|
|
|
|
|
|
|
|
# Matching roots
|
|
|
|
let
|
|
|
|
is_matching_source = data.source == justified_checkpoint
|
|
|
|
is_matching_target =
|
|
|
|
is_matching_source and
|
|
|
|
data.target.root == get_block_root(state, data.target.epoch)
|
|
|
|
is_matching_head =
|
|
|
|
is_matching_target and
|
|
|
|
data.beacon_block_root == get_block_root_at_slot(state, data.slot)
|
|
|
|
|
|
|
|
# Checked by check_attestation
|
|
|
|
doAssert is_matching_source
|
|
|
|
|
|
|
|
var participation_flag_indices: seq[int]
|
|
|
|
if is_matching_source and inclusion_delay <= integer_squareroot(SLOTS_PER_EPOCH):
|
|
|
|
participation_flag_indices.add(TIMELY_SOURCE_FLAG_INDEX)
|
|
|
|
if is_matching_target: # [Modified in Deneb:EIP7045]
|
|
|
|
participation_flag_indices.add(TIMELY_TARGET_FLAG_INDEX)
|
|
|
|
if is_matching_head and inclusion_delay == MIN_ATTESTATION_INCLUSION_DELAY:
|
|
|
|
participation_flag_indices.add(TIMELY_HEAD_FLAG_INDEX)
|
|
|
|
|
|
|
|
participation_flag_indices
|
|
|
|
|
2021-05-28 15:25:58 +00:00
|
|
|
# TODO these aren't great here
|
|
|
|
# TODO these duplicate some stuff in state_transition_epoch which uses TotalBalances
|
|
|
|
# better to centralize around that if feasible
|
|
|
|
|
2023-07-05 16:02:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#get_total_active_balance
|
2021-11-05 07:34:34 +00:00
|
|
|
func get_total_active_balance*(state: ForkyBeaconState, cache: var StateCache): Gwei =
|
2021-05-28 15:25:58 +00:00
|
|
|
## Return the combined effective balance of the active validators.
|
2023-05-05 20:37:56 +00:00
|
|
|
## Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei
|
|
|
|
## minimum to avoid divisions by zero.
|
2021-05-28 15:25:58 +00:00
|
|
|
|
|
|
|
let epoch = state.get_current_epoch()
|
|
|
|
|
2022-12-19 12:01:49 +00:00
|
|
|
cache.total_active_balance.withValue(epoch, tab) do:
|
|
|
|
return tab[]
|
|
|
|
do:
|
|
|
|
let tab = get_total_balance(
|
|
|
|
state, cache.get_shuffled_active_validator_indices(state, epoch))
|
|
|
|
cache.total_active_balance[epoch] = tab
|
|
|
|
return tab
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-07-05 16:02:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#get_base_reward_per_increment
|
2021-10-13 14:24:36 +00:00
|
|
|
func get_base_reward_per_increment_sqrt*(
|
|
|
|
total_active_balance_sqrt: uint64): Gwei =
|
|
|
|
EFFECTIVE_BALANCE_INCREMENT * BASE_REWARD_FACTOR div total_active_balance_sqrt
|
|
|
|
|
2021-07-01 08:55:16 +00:00
|
|
|
func get_base_reward_per_increment*(
|
2021-10-13 14:24:36 +00:00
|
|
|
total_active_balance: Gwei): Gwei =
|
|
|
|
get_base_reward_per_increment_sqrt(integer_squareroot(total_active_balance))
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-07-05 16:02:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/beacon-chain.md#get_base_reward
|
2021-06-28 06:54:06 +00:00
|
|
|
func get_base_reward(
|
2022-12-06 12:40:13 +00:00
|
|
|
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
2023-02-22 13:10:00 +00:00
|
|
|
deneb.BeaconState,
|
2022-10-27 06:29:24 +00:00
|
|
|
index: ValidatorIndex, base_reward_per_increment: Gwei): Gwei =
|
2021-06-28 06:54:06 +00:00
|
|
|
## Return the base reward for the validator defined by ``index`` with respect
|
|
|
|
## to the current ``state``.
|
|
|
|
let increments =
|
|
|
|
state.validators[index].effective_balance div EFFECTIVE_BALANCE_INCREMENT
|
|
|
|
increments * base_reward_per_increment
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-06-24 12:27:15 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/phase0/beacon-chain.md#attestations
|
2019-08-19 16:41:13 +00:00
|
|
|
proc check_attestation*(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
2020-07-27 16:04:44 +00:00
|
|
|
cache: var StateCache): Result[void, cstring] =
|
2018-12-11 17:55:45 +00:00
|
|
|
## Check that an attestation follows the rules of being included in the state
|
2018-12-27 20:14:37 +00:00
|
|
|
## at the current slot. When acting as a proposer, the same rules need to
|
|
|
|
## be followed!
|
2018-12-11 17:55:45 +00:00
|
|
|
|
2020-03-19 23:48:03 +00:00
|
|
|
let
|
|
|
|
data = attestation.data
|
2022-01-08 23:28:49 +00:00
|
|
|
epoch = ? check_attestation_target_epoch(data, state.get_current_epoch())
|
|
|
|
slot = ? check_attestation_slot_target(data)
|
|
|
|
committee_index = ? check_attestation_index(
|
2020-07-27 16:04:44 +00:00
|
|
|
data,
|
2022-01-08 23:28:49 +00:00
|
|
|
get_committee_count_per_slot(state, epoch, cache))
|
|
|
|
|
2023-06-24 12:27:15 +00:00
|
|
|
? check_attestation_inclusion((typeof state).toFork, slot, state.slot)
|
2019-08-14 08:56:32 +00:00
|
|
|
|
2020-07-27 16:04:44 +00:00
|
|
|
let committee_len = get_beacon_committee_len(
|
2022-01-08 23:28:49 +00:00
|
|
|
state, slot, committee_index, cache)
|
2020-07-27 10:59:57 +00:00
|
|
|
|
2020-07-27 16:04:44 +00:00
|
|
|
if attestation.aggregation_bits.lenu64 != committee_len:
|
|
|
|
return err("Inconsistent aggregation and committee length")
|
2019-06-24 09:21:56 +00:00
|
|
|
|
2022-01-08 23:28:49 +00:00
|
|
|
if epoch == get_current_epoch(state):
|
2020-07-27 16:04:44 +00:00
|
|
|
if not (data.source == state.current_justified_checkpoint):
|
|
|
|
return err("FFG data not matching current justified epoch")
|
2019-06-24 09:21:56 +00:00
|
|
|
else:
|
2020-07-27 16:04:44 +00:00
|
|
|
if not (data.source == state.previous_justified_checkpoint):
|
|
|
|
return err("FFG data not matching previous justified epoch")
|
2019-06-24 09:21:56 +00:00
|
|
|
|
2021-04-14 14:43:29 +00:00
|
|
|
? is_valid_indexed_attestation(state, attestation, flags, cache)
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2020-07-27 16:04:44 +00:00
|
|
|
ok()
|
2019-02-13 10:26:32 +00:00
|
|
|
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#new-process_bls_to_execution_change
|
2023-02-17 13:35:12 +00:00
|
|
|
proc check_bls_to_execution_change*(
|
2023-02-22 13:10:00 +00:00
|
|
|
genesisFork: Fork, state: capella.BeaconState | deneb.BeaconState,
|
2023-02-17 13:35:12 +00:00
|
|
|
signed_address_change: SignedBLSToExecutionChange, flags: UpdateFlags):
|
|
|
|
Result[void, cstring] =
|
|
|
|
let address_change = signed_address_change.message
|
|
|
|
|
|
|
|
if not (address_change.validator_index < state.validators.lenu64):
|
|
|
|
return err("process_bls_to_execution_change: invalid validator index")
|
|
|
|
|
|
|
|
var withdrawal_credentials =
|
|
|
|
state.validators.item(address_change.validator_index).withdrawal_credentials
|
|
|
|
|
|
|
|
if not (withdrawal_credentials.data[0] == BLS_WITHDRAWAL_PREFIX):
|
|
|
|
return err("process_bls_to_execution_change: invalid withdrawal prefix")
|
|
|
|
|
|
|
|
if not (withdrawal_credentials.data.toOpenArray(1, 31) ==
|
|
|
|
eth2digest(address_change.from_bls_pubkey.blob).data.toOpenArray(1, 31)):
|
|
|
|
return err("process_bls_to_execution_change: invalid withdrawal credentials")
|
|
|
|
|
|
|
|
doAssert flags + {skipBlsValidation} == {skipBlsValidation}
|
|
|
|
if skipBlsValidation notin flags and
|
|
|
|
not verify_bls_to_execution_change_signature(
|
|
|
|
genesisFork, state.genesis_validators_root, signed_address_change,
|
|
|
|
address_change.from_bls_pubkey, signed_address_change.signature):
|
|
|
|
return err("process_bls_to_execution_change: invalid signature")
|
|
|
|
|
|
|
|
ok()
|
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func get_proposer_reward*(state: ForkyBeaconState,
|
2021-12-29 02:50:49 +00:00
|
|
|
attestation: SomeAttestation,
|
|
|
|
base_reward_per_increment: Gwei,
|
|
|
|
cache: var StateCache,
|
|
|
|
epoch_participation: var EpochParticipationFlags): uint64 =
|
|
|
|
let participation_flag_indices = get_attestation_participation_flag_indices(
|
|
|
|
state, attestation.data, state.slot - attestation.data.slot)
|
|
|
|
for index in get_attesting_indices(
|
|
|
|
state, attestation.data, attestation.aggregation_bits, cache):
|
2022-12-19 12:01:49 +00:00
|
|
|
let
|
|
|
|
base_reward = get_base_reward(state, index, base_reward_per_increment)
|
2021-12-29 02:50:49 +00:00
|
|
|
for flag_index, weight in PARTICIPATION_FLAG_WEIGHTS:
|
|
|
|
if flag_index in participation_flag_indices and
|
2022-05-30 13:30:42 +00:00
|
|
|
not has_flag(epoch_participation.item(index), flag_index):
|
2022-12-19 12:01:49 +00:00
|
|
|
asList(epoch_participation)[index] =
|
2022-05-30 13:30:42 +00:00
|
|
|
add_flag(epoch_participation.item(index), flag_index)
|
2021-12-29 02:50:49 +00:00
|
|
|
# these are all valid; TODO statically verify or do it type-safely
|
2022-12-19 12:01:49 +00:00
|
|
|
result += base_reward * weight.uint64
|
2021-12-29 02:50:49 +00:00
|
|
|
|
|
|
|
let proposer_reward_denominator =
|
|
|
|
(WEIGHT_DENOMINATOR.uint64 - PROPOSER_WEIGHT.uint64) *
|
|
|
|
WEIGHT_DENOMINATOR.uint64 div PROPOSER_WEIGHT.uint64
|
|
|
|
|
|
|
|
return result div proposer_reward_denominator
|
|
|
|
|
2019-08-19 16:41:13 +00:00
|
|
|
proc process_attestation*(
|
2021-11-05 07:34:34 +00:00
|
|
|
state: var ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
2021-07-06 06:19:06 +00:00
|
|
|
base_reward_per_increment: Gwei, cache: var StateCache):
|
2021-12-03 14:46:56 +00:00
|
|
|
Result[void, cstring] =
|
2019-08-19 16:41:13 +00:00
|
|
|
# In the spec, attestation validation is mixed with state mutation, so here
|
|
|
|
# we've split it into two functions so that the validation logic can be
|
|
|
|
# reused when looking for suitable blocks to include in attestations.
|
2021-06-11 17:51:46 +00:00
|
|
|
#
|
|
|
|
# TODO this should be two separate functions, but
|
|
|
|
# https://github.com/nim-lang/Nim/issues/18202 means that this being called
|
|
|
|
# by process_operations() in state_transition_block fails that way.
|
2019-12-04 10:49:59 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
let proposer_index = get_beacon_proposer_index(state, cache).valueOr:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_attestation: no beacon proposer index and probably no active validators")
|
2019-12-04 10:49:59 +00:00
|
|
|
|
2020-07-27 16:04:44 +00:00
|
|
|
? check_attestation(state, attestation, flags, cache)
|
2019-08-19 16:41:13 +00:00
|
|
|
|
2021-05-28 15:25:58 +00:00
|
|
|
when state is phase0.BeaconState:
|
2023-06-24 12:27:15 +00:00
|
|
|
template addPendingAttestation(attestations: typed) =
|
|
|
|
# The genericSeqAssign generated by the compiler to copy the attestation
|
|
|
|
# data sadly is a processing hotspot - the business with the addDefault
|
|
|
|
# pointer is here simply to work around the poor codegen
|
|
|
|
let pa = attestations.addDefault()
|
|
|
|
if pa.isNil:
|
|
|
|
return err("process_attestation: too many pending attestations")
|
|
|
|
assign(pa[].aggregation_bits, attestation.aggregation_bits)
|
|
|
|
pa[].data = attestation.data
|
|
|
|
pa[].inclusion_delay = state.slot - attestation.data.slot
|
|
|
|
pa[].proposer_index = proposer_index.uint64
|
|
|
|
|
2021-07-06 06:19:06 +00:00
|
|
|
doAssert base_reward_per_increment == 0.Gwei
|
2021-05-28 15:25:58 +00:00
|
|
|
if attestation.data.target.epoch == get_current_epoch(state):
|
|
|
|
addPendingAttestation(state.current_epoch_attestations)
|
|
|
|
else:
|
|
|
|
addPendingAttestation(state.previous_epoch_attestations)
|
2022-10-27 06:29:24 +00:00
|
|
|
elif state is altair.BeaconState or state is bellatrix.BeaconState or
|
2023-02-22 13:10:00 +00:00
|
|
|
state is capella.BeaconState or state is deneb.BeaconState:
|
2023-06-24 12:27:15 +00:00
|
|
|
template updateParticipationFlags(epoch_participation: untyped) =
|
|
|
|
let proposer_reward = get_proposer_reward(
|
|
|
|
state, attestation, base_reward_per_increment, cache, epoch_participation)
|
|
|
|
increase_balance(state, proposer_index, proposer_reward)
|
|
|
|
|
2021-07-06 06:19:06 +00:00
|
|
|
doAssert base_reward_per_increment > 0.Gwei
|
2021-05-28 15:25:58 +00:00
|
|
|
if attestation.data.target.epoch == get_current_epoch(state):
|
|
|
|
updateParticipationFlags(state.current_epoch_participation)
|
|
|
|
else:
|
|
|
|
updateParticipationFlags(state.previous_epoch_participation)
|
2019-08-19 16:41:13 +00:00
|
|
|
else:
|
2021-05-28 15:25:58 +00:00
|
|
|
static: doAssert false
|
2020-07-27 16:04:44 +00:00
|
|
|
|
|
|
|
ok()
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-04-21 18:52:43 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/beacon-chain.md#get_next_sync_committee_indices
|
2022-10-27 06:29:24 +00:00
|
|
|
func get_next_sync_committee_keys(
|
2022-12-06 16:43:11 +00:00
|
|
|
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
2023-02-22 13:10:00 +00:00
|
|
|
deneb.BeaconState):
|
2021-10-13 14:24:36 +00:00
|
|
|
array[SYNC_COMMITTEE_SIZE, ValidatorPubKey] =
|
2022-01-27 19:52:08 +00:00
|
|
|
## Return the sequence of sync committee indices, with possible duplicates,
|
|
|
|
## for the next sync committee.
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
# The sync committe depends on seed and effective balance - it can
|
|
|
|
# thus only be computed for the current epoch of the state, after balance
|
|
|
|
# updates have been performed
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2021-05-31 12:54:53 +00:00
|
|
|
let epoch = get_current_epoch(state) + 1
|
2021-05-28 15:25:58 +00:00
|
|
|
|
|
|
|
const MAX_RANDOM_BYTE = 255
|
|
|
|
let
|
|
|
|
active_validator_indices = get_active_validator_indices(state, epoch)
|
|
|
|
active_validator_count = uint64(len(active_validator_indices))
|
|
|
|
seed = get_seed(state, epoch, DOMAIN_SYNC_COMMITTEE)
|
|
|
|
var
|
|
|
|
i = 0'u64
|
2021-10-13 14:24:36 +00:00
|
|
|
index = 0
|
|
|
|
res: array[SYNC_COMMITTEE_SIZE, ValidatorPubKey]
|
2021-05-28 15:25:58 +00:00
|
|
|
hash_buffer: array[40, byte]
|
|
|
|
hash_buffer[0..31] = seed.data
|
2021-10-13 14:24:36 +00:00
|
|
|
while index < SYNC_COMMITTEE_SIZE:
|
2022-01-08 20:06:34 +00:00
|
|
|
hash_buffer[32..39] = uint_to_bytes(uint64(i div 32))
|
2021-05-28 15:25:58 +00:00
|
|
|
let
|
2022-01-27 19:52:08 +00:00
|
|
|
shuffled_index = compute_shuffled_index(
|
|
|
|
uint64(i mod active_validator_count), active_validator_count, seed)
|
2021-05-28 15:25:58 +00:00
|
|
|
candidate_index = active_validator_indices[shuffled_index]
|
|
|
|
random_byte = eth2digest(hash_buffer).data[i mod 32]
|
|
|
|
effective_balance = state.validators[candidate_index].effective_balance
|
|
|
|
if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
|
2021-10-13 14:24:36 +00:00
|
|
|
res[index] = state.validators[candidate_index].pubkey
|
|
|
|
inc index
|
2021-05-28 15:25:58 +00:00
|
|
|
i += 1'u64
|
2021-10-13 14:24:36 +00:00
|
|
|
res
|
2021-05-28 15:25:58 +00:00
|
|
|
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/capella/beacon-chain.md#has_eth1_withdrawal_credential
|
2023-03-02 16:13:35 +00:00
|
|
|
func has_eth1_withdrawal_credential*(validator: Validator): bool =
|
2023-01-06 21:01:10 +00:00
|
|
|
## Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential.
|
|
|
|
validator.withdrawal_credentials.data[0] == ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
|
|
|
|
2023-04-21 18:52:43 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#is_fully_withdrawable_validator
|
2023-01-06 21:01:10 +00:00
|
|
|
func is_fully_withdrawable_validator(
|
|
|
|
validator: Validator, balance: Gwei, epoch: Epoch): bool =
|
|
|
|
## Check if ``validator`` is fully withdrawable.
|
|
|
|
has_eth1_withdrawal_credential(validator) and
|
|
|
|
validator.withdrawable_epoch <= epoch and balance > 0
|
|
|
|
|
2023-04-21 18:52:43 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#is_partially_withdrawable_validator
|
2023-01-06 21:01:10 +00:00
|
|
|
func is_partially_withdrawable_validator(
|
|
|
|
validator: Validator, balance: Gwei): bool =
|
|
|
|
## Check if ``validator`` is partially withdrawable.
|
|
|
|
let
|
|
|
|
has_max_effective_balance =
|
|
|
|
validator.effective_balance == MAX_EFFECTIVE_BALANCE
|
|
|
|
has_excess_balance = balance > MAX_EFFECTIVE_BALANCE
|
|
|
|
has_eth1_withdrawal_credential(validator) and
|
|
|
|
has_max_effective_balance and has_excess_balance
|
|
|
|
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#new-get_expected_withdrawals
|
2023-01-09 14:15:43 +00:00
|
|
|
func get_expected_withdrawals*(
|
2023-02-22 13:10:00 +00:00
|
|
|
state: capella.BeaconState | deneb.BeaconState): seq[Withdrawal] =
|
2023-01-06 21:01:10 +00:00
|
|
|
let
|
|
|
|
epoch = get_current_epoch(state)
|
|
|
|
num_validators = lenu64(state.validators)
|
|
|
|
var
|
|
|
|
withdrawal_index = state.next_withdrawal_index
|
|
|
|
validator_index = state.next_withdrawal_validator_index
|
|
|
|
withdrawals: seq[Withdrawal] = @[]
|
|
|
|
bound = min(len(state.validators), MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP)
|
|
|
|
for _ in 0 ..< bound:
|
|
|
|
let
|
|
|
|
validator = state.validators[validator_index]
|
|
|
|
balance = state.balances[validator_index]
|
|
|
|
if is_fully_withdrawable_validator(validator, balance, epoch):
|
|
|
|
var w = Withdrawal(
|
|
|
|
index: withdrawal_index,
|
|
|
|
validator_index: validator_index,
|
|
|
|
amount: balance)
|
|
|
|
w.address.data[0..19] = validator.withdrawal_credentials.data[12..^1]
|
|
|
|
withdrawals.add w
|
|
|
|
withdrawal_index = WithdrawalIndex(withdrawal_index + 1)
|
|
|
|
elif is_partially_withdrawable_validator(validator, balance):
|
|
|
|
var w = Withdrawal(
|
|
|
|
index: withdrawal_index,
|
|
|
|
validator_index: validator_index,
|
|
|
|
amount: balance - MAX_EFFECTIVE_BALANCE)
|
|
|
|
w.address.data[0..19] = validator.withdrawal_credentials.data[12..^1]
|
|
|
|
withdrawals.add w
|
|
|
|
withdrawal_index = WithdrawalIndex(withdrawal_index + 1)
|
|
|
|
if len(withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD:
|
|
|
|
break
|
|
|
|
validator_index = (validator_index + 1) mod num_validators
|
|
|
|
withdrawals
|
|
|
|
|
2023-05-05 20:37:56 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/beacon-chain.md#get_next_sync_committee
|
2022-10-27 06:29:24 +00:00
|
|
|
func get_next_sync_committee*(
|
2022-12-06 16:43:11 +00:00
|
|
|
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
2023-02-22 13:10:00 +00:00
|
|
|
deneb.BeaconState):
|
2021-09-27 14:22:58 +00:00
|
|
|
SyncCommittee =
|
2023-05-05 20:37:56 +00:00
|
|
|
## Return the next sync committee, with possible pubkey duplicates.
|
2021-06-14 17:42:46 +00:00
|
|
|
var res: SyncCommittee
|
2021-10-13 14:24:36 +00:00
|
|
|
res.pubkeys.data = get_next_sync_committee_keys(state)
|
2021-05-31 12:54:53 +00:00
|
|
|
|
2021-05-28 15:25:58 +00:00
|
|
|
# see signatures_batch, TODO shouldn't be here
|
2021-05-31 12:54:53 +00:00
|
|
|
# Deposit processing ensures all keys are valid
|
2021-06-14 17:42:46 +00:00
|
|
|
var attestersAgg: AggregatePublicKey
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
attestersAgg.init(res.pubkeys.data[0].load().get)
|
2021-06-14 17:42:46 +00:00
|
|
|
for i in 1 ..< res.pubkeys.data.len:
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
attestersAgg.aggregate(res.pubkeys.data[i].load().get)
|
2021-06-14 17:42:46 +00:00
|
|
|
|
|
|
|
res.aggregate_pubkey = finish(attestersAgg).toPubKey()
|
2021-05-28 15:25:58 +00:00
|
|
|
res
|
2021-05-31 12:54:53 +00:00
|
|
|
|
2023-06-13 14:03:49 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/beacon-chain.md#genesis
|
2023-02-23 02:10:07 +00:00
|
|
|
proc initialize_beacon_state_from_eth1*(
|
|
|
|
cfg: RuntimeConfig,
|
|
|
|
eth1_block_hash: Eth2Digest,
|
|
|
|
eth1_timestamp: uint64,
|
|
|
|
deposits: openArray[DepositData],
|
|
|
|
flags: UpdateFlags = {}): phase0.BeaconState =
|
|
|
|
## Get the genesis ``BeaconState``.
|
|
|
|
##
|
|
|
|
## Before the beacon chain starts, validators will register in the Eth1 chain
|
|
|
|
## and deposit ETH. When enough many validators have registered, a
|
|
|
|
## `ChainStart` log will be emitted and the beacon chain can start beaconing.
|
|
|
|
##
|
|
|
|
## Because the state root hash is part of the genesis block, the beacon state
|
|
|
|
## must be calculated before creating the genesis block.
|
|
|
|
|
|
|
|
# Induct validators
|
|
|
|
# Not in spec: the system doesn't work unless there are at least SLOTS_PER_EPOCH
|
|
|
|
# validators - there needs to be at least one member in each committee -
|
|
|
|
# good to know for testing, though arguably the system is not that useful at
|
2023-05-05 20:37:56 +00:00
|
|
|
# that point :)
|
2023-02-23 02:10:07 +00:00
|
|
|
doAssert deposits.lenu64 >= SLOTS_PER_EPOCH
|
|
|
|
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19094
|
|
|
|
template state(): untyped = result
|
|
|
|
state = phase0.BeaconState(
|
|
|
|
fork: genesisFork(cfg),
|
|
|
|
genesis_time: genesis_time_from_eth1_timestamp(cfg, eth1_timestamp),
|
|
|
|
eth1_data:
|
|
|
|
Eth1Data(block_hash: eth1_block_hash, deposit_count: uint64(len(deposits))),
|
|
|
|
latest_block_header:
|
|
|
|
BeaconBlockHeader(
|
|
|
|
body_root: hash_tree_root(default(phase0.BeaconBlockBody))))
|
|
|
|
|
|
|
|
# Seed RANDAO with Eth1 entropy
|
|
|
|
state.randao_mixes.fill(eth1_block_hash)
|
|
|
|
|
|
|
|
var merkleizer = createMerkleizer(DEPOSIT_CONTRACT_LIMIT)
|
|
|
|
for i, deposit in deposits:
|
|
|
|
let htr = hash_tree_root(deposit)
|
|
|
|
merkleizer.addChunk(htr.data)
|
|
|
|
|
|
|
|
# This is already known in the Eth1 monitor, but it would be too
|
|
|
|
# much work to refactor all the existing call sites in the test suite
|
|
|
|
state.eth1_data.deposit_root = mixInLength(merkleizer.getFinalHash(),
|
|
|
|
deposits.len)
|
|
|
|
state.eth1_deposit_index = deposits.lenu64
|
|
|
|
|
|
|
|
var pubkeyToIndex = initTable[ValidatorPubKey, ValidatorIndex]()
|
|
|
|
for idx, deposit in deposits:
|
|
|
|
let
|
|
|
|
pubkey = deposit.pubkey
|
|
|
|
amount = deposit.amount
|
|
|
|
|
|
|
|
pubkeyToIndex.withValue(pubkey, foundIdx) do:
|
|
|
|
# Increase balance by deposit amount
|
|
|
|
increase_balance(state, foundIdx[], amount)
|
|
|
|
do:
|
|
|
|
if skipBlsValidation in flags or
|
|
|
|
verify_deposit_signature(cfg, deposit):
|
|
|
|
pubkeyToIndex[pubkey] = ValidatorIndex(state.validators.len)
|
|
|
|
if not state.validators.add(get_validator_from_deposit(deposit)):
|
|
|
|
raiseAssert "too many validators"
|
|
|
|
if not state.balances.add(amount):
|
|
|
|
raiseAssert "same as validators"
|
|
|
|
|
|
|
|
else:
|
|
|
|
# Invalid deposits are perfectly possible
|
|
|
|
trace "Skipping deposit with invalid signature",
|
|
|
|
deposit = shortLog(deposit)
|
|
|
|
|
|
|
|
# Process activations
|
|
|
|
for vidx in state.validators.vindices:
|
|
|
|
let
|
|
|
|
balance = state.balances.item(vidx)
|
|
|
|
validator = addr state.validators.mitem(vidx)
|
|
|
|
|
|
|
|
validator.effective_balance = min(
|
|
|
|
balance - balance mod EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
|
|
|
|
|
|
|
if validator.effective_balance == MAX_EFFECTIVE_BALANCE:
|
|
|
|
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
|
|
|
validator.activation_epoch = GENESIS_EPOCH
|
|
|
|
|
|
|
|
# Set genesis validators root for domain separation and chain versioning
|
|
|
|
state.genesis_validators_root = hash_tree_root(state.validators)
|
|
|
|
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19094
|
|
|
|
# state
|
|
|
|
|
|
|
|
proc initialize_hashed_beacon_state_from_eth1*(
|
|
|
|
cfg: RuntimeConfig,
|
|
|
|
eth1_block_hash: Eth2Digest,
|
|
|
|
eth1_timestamp: uint64,
|
|
|
|
deposits: openArray[DepositData],
|
|
|
|
flags: UpdateFlags = {}): phase0.HashedBeaconState =
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19094
|
|
|
|
result = phase0.HashedBeaconState(
|
|
|
|
data: initialize_beacon_state_from_eth1(
|
|
|
|
cfg, eth1_block_hash, eth1_timestamp, deposits, flags))
|
|
|
|
result.root = hash_tree_root(result.data)
|
|
|
|
|
2023-04-21 18:52:43 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/beacon-chain.md#testing
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/capella/beacon-chain.md#testing
|
2023-05-05 20:38:51 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#testing
|
2023-02-23 02:10:07 +00:00
|
|
|
proc initialize_beacon_state_from_eth1*(
|
|
|
|
cfg: RuntimeConfig,
|
|
|
|
eth1_block_hash: Eth2Digest,
|
|
|
|
eth1_timestamp: uint64,
|
|
|
|
deposits: openArray[DepositData],
|
|
|
|
execution_payload_header: ForkyExecutionPayloadHeader,
|
|
|
|
flags: UpdateFlags = {}): auto =
|
|
|
|
## Get the genesis ``BeaconState``.
|
|
|
|
##
|
|
|
|
## Before the beacon chain starts, validators will register in the Eth1 chain
|
|
|
|
## and deposit ETH. When enough many validators have registered, a
|
|
|
|
## `ChainStart` log will be emitted and the beacon chain can start beaconing.
|
|
|
|
##
|
|
|
|
## Because the state root hash is part of the genesis block, the beacon state
|
|
|
|
## must be calculated before creating the genesis block.
|
|
|
|
|
|
|
|
# Induct validators
|
|
|
|
# Not in spec: the system doesn't work unless there are at least SLOTS_PER_EPOCH
|
|
|
|
# validators - there needs to be at least one member in each committee -
|
|
|
|
# good to know for testing, though arguably the system is not that useful at
|
|
|
|
# at that point :)
|
|
|
|
doAssert deposits.lenu64 >= SLOTS_PER_EPOCH
|
|
|
|
|
|
|
|
const consensusFork = typeof(execution_payload_header).toFork
|
|
|
|
let
|
|
|
|
forkVersion = cfg.forkVersion(consensusFork)
|
|
|
|
fork = Fork(
|
|
|
|
previous_version: forkVersion,
|
|
|
|
current_version: forkVersion,
|
|
|
|
epoch: GENESIS_EPOCH)
|
|
|
|
|
|
|
|
type BeaconState = BeaconStateType(consensusFork)
|
|
|
|
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19094
|
|
|
|
template state(): untyped = result
|
|
|
|
result = BeaconState(
|
|
|
|
fork: fork,
|
|
|
|
genesis_time: genesis_time_from_eth1_timestamp(cfg, eth1_timestamp),
|
|
|
|
eth1_data:
|
|
|
|
Eth1Data(block_hash: eth1_block_hash, deposit_count: uint64(len(deposits))),
|
|
|
|
latest_block_header:
|
|
|
|
BeaconBlockHeader(
|
|
|
|
body_root: hash_tree_root(default BeaconBlockBodyType(consensusFork))))
|
|
|
|
|
|
|
|
# Seed RANDAO with Eth1 entropy
|
|
|
|
state.randao_mixes.data.fill(eth1_block_hash)
|
|
|
|
|
|
|
|
var merkleizer = createMerkleizer(DEPOSIT_CONTRACT_LIMIT)
|
|
|
|
for i, deposit in deposits:
|
|
|
|
let htr = hash_tree_root(deposit)
|
|
|
|
merkleizer.addChunk(htr.data)
|
|
|
|
|
|
|
|
# This is already known in the Eth1 monitor, but it would be too
|
|
|
|
# much work to refactor all the existing call sites in the test suite
|
|
|
|
state.eth1_data.deposit_root = mixInLength(merkleizer.getFinalHash(),
|
|
|
|
deposits.len)
|
|
|
|
state.eth1_deposit_index = deposits.lenu64
|
|
|
|
|
|
|
|
var pubkeyToIndex = initTable[ValidatorPubKey, ValidatorIndex]()
|
|
|
|
for idx, deposit in deposits:
|
|
|
|
let
|
|
|
|
pubkey = deposit.pubkey
|
|
|
|
amount = deposit.amount
|
|
|
|
|
|
|
|
pubkeyToIndex.withValue(pubkey, foundIdx) do:
|
|
|
|
# Increase balance by deposit amount
|
|
|
|
increase_balance(state, foundIdx[], amount)
|
|
|
|
do:
|
|
|
|
if skipBlsValidation in flags or
|
|
|
|
verify_deposit_signature(cfg, deposit):
|
|
|
|
pubkeyToIndex[pubkey] = ValidatorIndex(state.validators.len)
|
|
|
|
if not state.validators.add(get_validator_from_deposit(deposit)):
|
|
|
|
raiseAssert "too many validators"
|
|
|
|
if not state.balances.add(amount):
|
|
|
|
raiseAssert "same as validators"
|
|
|
|
|
|
|
|
else:
|
|
|
|
# Invalid deposits are perfectly possible
|
|
|
|
trace "Skipping deposit with invalid signature",
|
|
|
|
deposit = shortLog(deposit)
|
|
|
|
|
|
|
|
# Initialize epoch participations - TODO (This must be added to the spec)
|
|
|
|
var
|
|
|
|
empty_participation: EpochParticipationFlags
|
|
|
|
inactivity_scores = HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]()
|
|
|
|
|
|
|
|
doAssert empty_participation.asList.setLen(state.validators.len)
|
|
|
|
doAssert inactivity_scores.data.setLen(state.validators.len)
|
|
|
|
inactivity_scores.resetCache()
|
|
|
|
|
|
|
|
state.previous_epoch_participation = empty_participation
|
|
|
|
state.current_epoch_participation = empty_participation
|
|
|
|
state.inactivity_scores = inactivity_scores
|
|
|
|
|
|
|
|
# Process activations
|
|
|
|
for vidx in state.validators.vindices:
|
|
|
|
let
|
|
|
|
balance = state.balances.item(vidx)
|
|
|
|
validator = addr state.validators.mitem(vidx)
|
|
|
|
|
|
|
|
validator.effective_balance = min(
|
|
|
|
balance - balance mod EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
|
|
|
|
|
|
|
if validator.effective_balance == MAX_EFFECTIVE_BALANCE:
|
|
|
|
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
|
|
|
validator.activation_epoch = GENESIS_EPOCH
|
|
|
|
|
|
|
|
# Set genesis validators root for domain separation and chain versioning
|
|
|
|
state.genesis_validators_root = hash_tree_root(state.validators)
|
|
|
|
|
|
|
|
# Fill in sync committees
|
|
|
|
# Note: A duplicate committee is assigned for the current and next committee at genesis
|
|
|
|
state.current_sync_committee = get_next_sync_committee(state)
|
|
|
|
state.next_sync_committee = get_next_sync_committee(state)
|
|
|
|
|
|
|
|
# [New in Bellatrix] Initialize the execution payload header
|
|
|
|
# If empty, will initialize a chain that has not yet gone through the Merge transition
|
|
|
|
state.latest_execution_payload_header = execution_payload_header
|
|
|
|
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19094
|
|
|
|
# state
|
|
|
|
|
|
|
|
proc initialize_hashed_beacon_state_from_eth1*(
|
|
|
|
cfg: RuntimeConfig,
|
|
|
|
eth1_block_hash: Eth2Digest,
|
|
|
|
eth1_timestamp: uint64,
|
|
|
|
deposits: openArray[DepositData],
|
|
|
|
execution_payload_header: ForkyExecutionPayloadHeader,
|
|
|
|
flags: UpdateFlags = {}): auto =
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19094
|
|
|
|
result = initHashedBeaconState(
|
|
|
|
initialize_beacon_state_from_eth1(
|
|
|
|
cfg, eth1_block_hash, eth1_timestamp, deposits,
|
|
|
|
execution_payload_header, flags))
|
|
|
|
result.root = hash_tree_root(result.data)
|
|
|
|
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/altair/fork.md#upgrading-the-state
|
2021-05-31 12:54:53 +00:00
|
|
|
func translate_participation(
|
|
|
|
state: var altair.BeaconState,
|
|
|
|
pending_attestations: openArray[phase0.PendingAttestation]) =
|
2021-06-25 12:51:25 +00:00
|
|
|
|
|
|
|
var cache = StateCache()
|
2021-05-31 12:54:53 +00:00
|
|
|
for attestation in pending_attestations:
|
|
|
|
let
|
|
|
|
data = attestation.data
|
|
|
|
inclusion_delay = attestation.inclusion_delay
|
|
|
|
|
|
|
|
# Translate attestation inclusion info to flag indices
|
|
|
|
participation_flag_indices =
|
|
|
|
get_attestation_participation_flag_indices(state, data, inclusion_delay)
|
|
|
|
|
|
|
|
# Apply flags to all attesting validators
|
|
|
|
for index in get_attesting_indices(
|
|
|
|
state, data, attestation.aggregation_bits, cache):
|
|
|
|
for flag_index in participation_flag_indices:
|
|
|
|
state.previous_epoch_participation[index] =
|
2022-05-30 13:30:42 +00:00
|
|
|
add_flag(state.previous_epoch_participation.item(index), flag_index)
|
2021-05-31 12:54:53 +00:00
|
|
|
|
2022-02-17 11:53:55 +00:00
|
|
|
func upgrade_to_altair*(cfg: RuntimeConfig, pre: phase0.BeaconState):
|
|
|
|
ref altair.BeaconState =
|
2021-05-31 12:54:53 +00:00
|
|
|
var
|
2022-06-20 05:38:56 +00:00
|
|
|
empty_participation: EpochParticipationFlags
|
2021-05-31 12:54:53 +00:00
|
|
|
inactivity_scores = HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]()
|
2021-06-25 12:51:25 +00:00
|
|
|
|
2022-12-19 12:01:49 +00:00
|
|
|
doAssert empty_participation.asList.setLen(pre.validators.len)
|
2021-06-25 12:51:25 +00:00
|
|
|
|
|
|
|
doAssert inactivity_scores.data.setLen(pre.validators.len)
|
|
|
|
inactivity_scores.resetCache()
|
2021-05-31 12:54:53 +00:00
|
|
|
|
2022-02-20 20:13:06 +00:00
|
|
|
let post = (ref altair.BeaconState)(
|
2021-05-31 12:54:53 +00:00
|
|
|
genesis_time: pre.genesis_time,
|
|
|
|
genesis_validators_root: pre.genesis_validators_root,
|
|
|
|
slot: pre.slot,
|
2021-08-10 20:46:35 +00:00
|
|
|
fork: altairFork(cfg),
|
2021-05-31 12:54:53 +00:00
|
|
|
|
|
|
|
# History
|
|
|
|
latest_block_header: pre.latest_block_header,
|
|
|
|
block_roots: pre.block_roots,
|
|
|
|
state_roots: pre.state_roots,
|
|
|
|
historical_roots: pre.historical_roots,
|
|
|
|
|
|
|
|
# Eth1
|
|
|
|
eth1_data: pre.eth1_data,
|
|
|
|
eth1_data_votes: pre.eth1_data_votes,
|
|
|
|
eth1_deposit_index: pre.eth1_deposit_index,
|
|
|
|
|
|
|
|
# Registry
|
|
|
|
validators: pre.validators,
|
|
|
|
balances: pre.balances,
|
|
|
|
|
|
|
|
# Randomness
|
|
|
|
randao_mixes: pre.randao_mixes,
|
|
|
|
|
|
|
|
# Slashings
|
|
|
|
slashings: pre.slashings,
|
|
|
|
|
|
|
|
# Attestations
|
|
|
|
previous_epoch_participation: empty_participation,
|
|
|
|
current_epoch_participation: empty_participation,
|
|
|
|
|
|
|
|
# Finality
|
|
|
|
justification_bits: pre.justification_bits,
|
|
|
|
previous_justified_checkpoint: pre.previous_justified_checkpoint,
|
|
|
|
current_justified_checkpoint: pre.current_justified_checkpoint,
|
|
|
|
finalized_checkpoint: pre.finalized_checkpoint,
|
|
|
|
|
|
|
|
# Inactivity
|
|
|
|
inactivity_scores: inactivity_scores
|
|
|
|
)
|
|
|
|
|
|
|
|
# Fill in previous epoch participation from the pre state's pending
|
|
|
|
# attestations
|
2021-06-04 10:38:00 +00:00
|
|
|
translate_participation(post[], pre.previous_epoch_attestations.asSeq)
|
2021-05-31 12:54:53 +00:00
|
|
|
|
|
|
|
# Fill in sync committees
|
|
|
|
# Note: A duplicate committee is assigned for the current and next committee
|
|
|
|
# at the fork boundary
|
2021-06-04 10:38:00 +00:00
|
|
|
post[].current_sync_committee = get_next_sync_committee(post[])
|
|
|
|
post[].next_sync_committee = get_next_sync_committee(post[])
|
2021-05-31 12:54:53 +00:00
|
|
|
|
|
|
|
post
|
2021-09-11 08:01:05 +00:00
|
|
|
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/bellatrix/fork.md#upgrading-the-state
|
2022-01-10 09:39:43 +00:00
|
|
|
func upgrade_to_bellatrix*(cfg: RuntimeConfig, pre: altair.BeaconState):
|
2022-01-06 11:25:35 +00:00
|
|
|
ref bellatrix.BeaconState =
|
2021-09-11 08:01:05 +00:00
|
|
|
let epoch = get_current_epoch(pre)
|
2022-01-06 11:25:35 +00:00
|
|
|
(ref bellatrix.BeaconState)(
|
2021-09-11 08:01:05 +00:00
|
|
|
# Versioning
|
|
|
|
genesis_time: pre.genesis_time,
|
|
|
|
genesis_validators_root: pre.genesis_validators_root,
|
|
|
|
slot: pre.slot,
|
|
|
|
fork: Fork(
|
|
|
|
previous_version: pre.fork.current_version,
|
2022-01-20 08:30:33 +00:00
|
|
|
current_version: cfg.BELLATRIX_FORK_VERSION,
|
2021-09-11 08:01:05 +00:00
|
|
|
epoch: epoch,
|
|
|
|
),
|
|
|
|
|
|
|
|
# History
|
|
|
|
latest_block_header: pre.latest_block_header,
|
|
|
|
block_roots: pre.block_roots,
|
|
|
|
state_roots: pre.state_roots,
|
|
|
|
historical_roots: pre.historical_roots,
|
|
|
|
|
|
|
|
# Eth1
|
|
|
|
eth1_data: pre.eth1_data,
|
|
|
|
eth1_data_votes: pre.eth1_data_votes,
|
|
|
|
eth1_deposit_index: pre.eth1_deposit_index,
|
|
|
|
|
|
|
|
# Registry
|
|
|
|
validators: pre.validators,
|
|
|
|
balances: pre.balances,
|
|
|
|
|
|
|
|
# Randomness
|
|
|
|
randao_mixes: pre.randao_mixes,
|
|
|
|
|
|
|
|
# Slashings
|
|
|
|
slashings: pre.slashings,
|
|
|
|
|
|
|
|
# Participation
|
|
|
|
previous_epoch_participation: pre.previous_epoch_participation,
|
|
|
|
current_epoch_participation: pre.current_epoch_participation,
|
|
|
|
|
|
|
|
# Finality
|
|
|
|
justification_bits: pre.justification_bits,
|
|
|
|
previous_justified_checkpoint: pre.previous_justified_checkpoint,
|
|
|
|
current_justified_checkpoint: pre.current_justified_checkpoint,
|
|
|
|
finalized_checkpoint: pre.finalized_checkpoint,
|
|
|
|
|
|
|
|
# Inactivity
|
|
|
|
inactivity_scores: pre.inactivity_scores,
|
|
|
|
|
|
|
|
# Sync
|
|
|
|
current_sync_committee: pre.current_sync_committee,
|
|
|
|
next_sync_committee: pre.next_sync_committee,
|
|
|
|
|
|
|
|
# Execution-layer
|
2022-10-27 06:29:24 +00:00
|
|
|
latest_execution_payload_header: default(bellatrix.ExecutionPayloadHeader)
|
|
|
|
)
|
|
|
|
|
2023-06-24 15:43:30 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.0/specs/capella/fork.md#upgrading-the-state
|
2022-10-27 06:29:24 +00:00
|
|
|
func upgrade_to_capella*(cfg: RuntimeConfig, pre: bellatrix.BeaconState):
|
|
|
|
ref capella.BeaconState =
|
|
|
|
let
|
|
|
|
epoch = get_current_epoch(pre)
|
|
|
|
latest_execution_payload_header = capella.ExecutionPayloadHeader(
|
|
|
|
parent_hash: pre.latest_execution_payload_header.parent_hash,
|
|
|
|
fee_recipient: pre.latest_execution_payload_header.fee_recipient,
|
|
|
|
state_root: pre.latest_execution_payload_header.state_root,
|
|
|
|
receipts_root: pre.latest_execution_payload_header.receipts_root,
|
|
|
|
logs_bloom: pre.latest_execution_payload_header.logs_bloom,
|
|
|
|
prev_randao: pre.latest_execution_payload_header.prev_randao,
|
|
|
|
block_number: pre.latest_execution_payload_header.block_number,
|
|
|
|
gas_limit: pre.latest_execution_payload_header.gas_limit,
|
|
|
|
gas_used: pre.latest_execution_payload_header.gas_used,
|
|
|
|
timestamp: pre.latest_execution_payload_header.timestamp,
|
|
|
|
extra_data: pre.latest_execution_payload_header.extra_data,
|
|
|
|
base_fee_per_gas: pre.latest_execution_payload_header.base_fee_per_gas,
|
|
|
|
block_hash: pre.latest_execution_payload_header.block_hash,
|
|
|
|
transactions_root: pre.latest_execution_payload_header.transactions_root,
|
|
|
|
withdrawals_root: Eth2Digest() # [New in Capella]
|
|
|
|
)
|
|
|
|
|
|
|
|
(ref capella.BeaconState)(
|
|
|
|
# Versioning
|
|
|
|
genesis_time: pre.genesis_time,
|
|
|
|
genesis_validators_root: pre.genesis_validators_root,
|
|
|
|
slot: pre.slot,
|
|
|
|
fork: Fork(
|
|
|
|
previous_version: pre.fork.current_version,
|
|
|
|
current_version: cfg.CAPELLA_FORK_VERSION,
|
|
|
|
epoch: epoch,
|
|
|
|
),
|
|
|
|
|
|
|
|
# History
|
|
|
|
latest_block_header: pre.latest_block_header,
|
|
|
|
block_roots: pre.block_roots,
|
|
|
|
state_roots: pre.state_roots,
|
|
|
|
historical_roots: pre.historical_roots,
|
|
|
|
|
|
|
|
# Eth1
|
|
|
|
eth1_data: pre.eth1_data,
|
|
|
|
eth1_data_votes: pre.eth1_data_votes,
|
|
|
|
eth1_deposit_index: pre.eth1_deposit_index,
|
|
|
|
|
|
|
|
# Registry
|
|
|
|
validators: pre.validators,
|
|
|
|
balances: pre.balances,
|
|
|
|
|
|
|
|
# Randomness
|
|
|
|
randao_mixes: pre.randao_mixes,
|
|
|
|
|
|
|
|
# Slashings
|
|
|
|
slashings: pre.slashings,
|
|
|
|
|
|
|
|
# Participation
|
|
|
|
previous_epoch_participation: pre.previous_epoch_participation,
|
|
|
|
current_epoch_participation: pre.current_epoch_participation,
|
|
|
|
|
|
|
|
# Finality
|
|
|
|
justification_bits: pre.justification_bits,
|
|
|
|
previous_justified_checkpoint: pre.previous_justified_checkpoint,
|
|
|
|
current_justified_checkpoint: pre.current_justified_checkpoint,
|
|
|
|
finalized_checkpoint: pre.finalized_checkpoint,
|
|
|
|
|
|
|
|
# Inactivity
|
|
|
|
inactivity_scores: pre.inactivity_scores,
|
|
|
|
|
|
|
|
# Sync
|
|
|
|
current_sync_committee: pre.current_sync_committee,
|
|
|
|
next_sync_committee: pre.next_sync_committee,
|
|
|
|
|
|
|
|
# Execution-layer
|
|
|
|
latest_execution_payload_header: latest_execution_payload_header,
|
|
|
|
|
|
|
|
# Withdrawals
|
|
|
|
next_withdrawal_index: 0,
|
2022-11-21 07:44:49 +00:00
|
|
|
next_withdrawal_validator_index: 0
|
2023-04-18 22:00:06 +00:00
|
|
|
|
|
|
|
# Deep history valid from Capella onwards [New in Capella]
|
|
|
|
# historical_summaries initialized to correct default automatically
|
2021-09-11 08:01:05 +00:00
|
|
|
)
|
2021-11-07 21:03:23 +00:00
|
|
|
|
2023-06-03 21:55:08 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/deneb/fork.md#upgrading-the-state
|
2023-03-11 14:28:55 +00:00
|
|
|
func upgrade_to_deneb*(cfg: RuntimeConfig, pre: capella.BeaconState):
|
2023-02-22 13:10:00 +00:00
|
|
|
ref deneb.BeaconState =
|
2022-12-06 16:43:11 +00:00
|
|
|
let
|
|
|
|
epoch = get_current_epoch(pre)
|
2023-02-22 13:10:00 +00:00
|
|
|
latest_execution_payload_header = deneb.ExecutionPayloadHeader(
|
2022-12-06 16:43:11 +00:00
|
|
|
parent_hash: pre.latest_execution_payload_header.parent_hash,
|
|
|
|
fee_recipient: pre.latest_execution_payload_header.fee_recipient,
|
|
|
|
state_root: pre.latest_execution_payload_header.state_root,
|
|
|
|
receipts_root: pre.latest_execution_payload_header.receipts_root,
|
|
|
|
logs_bloom: pre.latest_execution_payload_header.logs_bloom,
|
|
|
|
prev_randao: pre.latest_execution_payload_header.prev_randao,
|
|
|
|
block_number: pre.latest_execution_payload_header.block_number,
|
|
|
|
gas_limit: pre.latest_execution_payload_header.gas_limit,
|
|
|
|
gas_used: pre.latest_execution_payload_header.gas_used,
|
|
|
|
timestamp: pre.latest_execution_payload_header.timestamp,
|
|
|
|
extra_data: pre.latest_execution_payload_header.extra_data,
|
|
|
|
base_fee_per_gas: pre.latest_execution_payload_header.base_fee_per_gas,
|
|
|
|
block_hash: pre.latest_execution_payload_header.block_hash,
|
|
|
|
transactions_root: pre.latest_execution_payload_header.transactions_root,
|
2023-05-05 23:15:47 +00:00
|
|
|
withdrawals_root: pre.latest_execution_payload_header.withdrawals_root,
|
2023-06-03 21:55:08 +00:00
|
|
|
data_gas_used: 0, # [New in Deneb]
|
|
|
|
excess_data_gas: 0 # [New in Deneb]
|
2022-12-06 16:43:11 +00:00
|
|
|
)
|
|
|
|
|
2023-02-22 13:10:00 +00:00
|
|
|
(ref deneb.BeaconState)(
|
2022-12-06 16:43:11 +00:00
|
|
|
# Versioning
|
|
|
|
genesis_time: pre.genesis_time,
|
|
|
|
genesis_validators_root: pre.genesis_validators_root,
|
|
|
|
slot: pre.slot,
|
|
|
|
fork: Fork(
|
|
|
|
previous_version: pre.fork.current_version,
|
2023-03-11 14:28:55 +00:00
|
|
|
current_version: cfg.DENEB_FORK_VERSION, # [Modified in Deneb]
|
2022-12-06 16:43:11 +00:00
|
|
|
epoch: epoch
|
|
|
|
),
|
|
|
|
|
|
|
|
# History
|
|
|
|
latest_block_header: pre.latest_block_header,
|
|
|
|
block_roots: pre.block_roots,
|
|
|
|
state_roots: pre.state_roots,
|
|
|
|
historical_roots: pre.historical_roots,
|
|
|
|
|
|
|
|
# Eth1
|
|
|
|
eth1_data: pre.eth1_data,
|
|
|
|
eth1_data_votes: pre.eth1_data_votes,
|
|
|
|
eth1_deposit_index: pre.eth1_deposit_index,
|
|
|
|
|
|
|
|
# Registry
|
|
|
|
validators: pre.validators,
|
|
|
|
balances: pre.balances,
|
|
|
|
|
|
|
|
# Randomness
|
|
|
|
randao_mixes: pre.randao_mixes,
|
|
|
|
|
|
|
|
# Slashings
|
|
|
|
slashings: pre.slashings,
|
|
|
|
|
|
|
|
# Participation
|
|
|
|
previous_epoch_participation: pre.previous_epoch_participation,
|
|
|
|
current_epoch_participation: pre.current_epoch_participation,
|
|
|
|
|
|
|
|
# Finality
|
|
|
|
justification_bits: pre.justification_bits,
|
|
|
|
previous_justified_checkpoint: pre.previous_justified_checkpoint,
|
|
|
|
current_justified_checkpoint: pre.current_justified_checkpoint,
|
|
|
|
finalized_checkpoint: pre.finalized_checkpoint,
|
|
|
|
|
|
|
|
# Inactivity
|
|
|
|
inactivity_scores: pre.inactivity_scores,
|
2023-03-11 14:28:55 +00:00
|
|
|
|
2022-12-06 16:43:11 +00:00
|
|
|
# Sync
|
|
|
|
current_sync_committee: pre.current_sync_committee,
|
|
|
|
next_sync_committee: pre.next_sync_committee,
|
|
|
|
|
|
|
|
# Execution-layer
|
2023-03-11 14:28:55 +00:00
|
|
|
latest_execution_payload_header: latest_execution_payload_header, # [Modified in Deneb]
|
2022-12-06 16:43:11 +00:00
|
|
|
|
|
|
|
# Withdrawals
|
|
|
|
next_withdrawal_index: pre.next_withdrawal_index,
|
2023-01-11 17:21:16 +00:00
|
|
|
next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
|
|
|
|
|
|
|
|
# Deep history valid from Capella onwards
|
|
|
|
historical_summaries: pre.historical_summaries
|
2022-12-06 16:43:11 +00:00
|
|
|
)
|
|
|
|
|
2021-11-09 19:21:36 +00:00
|
|
|
template isValidInState*(idx: ValidatorIndex, state: ForkyBeaconState): bool =
|
|
|
|
idx.uint64 < state.validators.lenu64
|
2021-11-07 21:03:23 +00:00
|
|
|
|
2021-11-18 12:02:43 +00:00
|
|
|
func latest_block_root*(state: ForkyBeaconState, state_root: Eth2Digest): Eth2Digest =
|
|
|
|
# The root of the last block that was successfully applied to this state -
|
|
|
|
# normally, when a block is applied, the data from the header is stored in
|
|
|
|
# the state without the state root - on the next process_slot, the state root
|
|
|
|
# is added to the header and the block root can now be computed and added to
|
|
|
|
# the block roots table. If process_slot has not yet run on top of the new
|
|
|
|
# block, we must fill in the state root ourselves.
|
|
|
|
if state.slot == state.latest_block_header.slot:
|
|
|
|
# process_slot will not yet have updated the header of the "current" block -
|
|
|
|
# similar to block creation, we fill it in with the state root
|
|
|
|
var tmp = state.latest_block_header
|
|
|
|
tmp.state_root = state_root
|
|
|
|
hash_tree_root(tmp)
|
|
|
|
elif state.slot <=
|
|
|
|
(state.latest_block_header.slot + SLOTS_PER_HISTORICAL_ROOT):
|
|
|
|
# block_roots is limited to about a day - see assert in
|
|
|
|
# `get_block_root_at_slot`
|
|
|
|
state.get_block_root_at_slot(state.latest_block_header.slot)
|
|
|
|
else:
|
|
|
|
# Reallly long periods of empty slots - unlikely but possible
|
|
|
|
hash_tree_root(state.latest_block_header)
|
|
|
|
|
|
|
|
func latest_block_root*(state: ForkyHashedBeaconState): Eth2Digest =
|
|
|
|
latest_block_root(state.data, state.root)
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
|
2022-03-16 07:20:40 +00:00
|
|
|
func latest_block_root*(state: ForkedHashedBeaconState): Eth2Digest =
|
2022-09-13 11:53:12 +00:00
|
|
|
withState(state): latest_block_root(forkyState)
|
2022-03-16 07:20:40 +00:00
|
|
|
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
func get_sync_committee_cache*(
|
2022-12-06 12:40:13 +00:00
|
|
|
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
2023-02-22 13:10:00 +00:00
|
|
|
deneb.BeaconState,
|
2022-10-27 06:29:24 +00:00
|
|
|
cache: var StateCache): SyncCommitteeCache =
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
let period = state.slot.sync_committee_period()
|
|
|
|
|
|
|
|
cache.sync_committees.withValue(period, v) do:
|
|
|
|
return v[]
|
|
|
|
|
|
|
|
var
|
|
|
|
s = toHashSet(state.current_sync_committee.pubkeys.data)
|
|
|
|
|
|
|
|
for pk in state.next_sync_committee.pubkeys.data:
|
|
|
|
s.incl(pk)
|
|
|
|
|
|
|
|
var pubkeyIndices: Table[ValidatorPubKey, ValidatorIndex]
|
2022-05-23 23:39:08 +00:00
|
|
|
for vidx in state.validators.vindices:
|
|
|
|
let pubkey = state.validators[vidx].pubkey
|
|
|
|
if pubkey in s:
|
|
|
|
pubkeyIndices[pubkey] = vidx
|
Speed up altair block processing 2x (#3115)
* Speed up altair block processing >2x
Like #3089, this PR drastially speeds up historical REST queries and
other long state replays.
* cache sync committee validator indices
* use ~80mb less memory for validator pubkey mappings
* batch-verify sync aggregate signature (fixes #2985)
* document sync committee hack with head block vs sync message block
* add batch signature verification failure tests
Before:
```
../env.sh nim c -d:release -r ncli_db --db:mainnet_0/db bench --start-slot:-1000
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
5830.675, 0.000, 5830.675, 5830.675, 1, Initialize DB
0.481, 1.878, 0.215, 59.167, 981, Load block from database
8422.566, 0.000, 8422.566, 8422.566, 1, Load state from database
6.996, 1.678, 0.042, 14.385, 969, Advance slot, non-epoch
93.217, 8.318, 84.192, 122.209, 32, Advance slot, epoch
20.513, 23.665, 11.510, 201.561, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
After:
```
7081.422, 0.000, 7081.422, 7081.422, 1, Initialize DB
0.553, 2.122, 0.175, 66.692, 981, Load block from database
5439.446, 0.000, 5439.446, 5439.446, 1, Load state from database
6.829, 1.575, 0.043, 12.156, 969, Advance slot, non-epoch
94.716, 2.749, 88.395, 100.026, 32, Advance slot, epoch
11.636, 23.766, 4.889, 205.250, 981, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database load
0.000, 0.000, 0.000, 0.000, 0, Database store
```
* add comment
2021-11-24 12:43:50 +00:00
|
|
|
|
|
|
|
var res: SyncCommitteeCache
|
|
|
|
try:
|
|
|
|
for i in 0..<res.current_sync_committee.len():
|
|
|
|
res.current_sync_committee[i] =
|
|
|
|
pubkeyIndices[state.current_sync_committee.pubkeys[i]]
|
|
|
|
res.next_sync_committee[i] =
|
|
|
|
pubkeyIndices[state.next_sync_committee.pubkeys[i]]
|
|
|
|
except KeyError:
|
|
|
|
raiseAssert "table constructed just above"
|
|
|
|
|
|
|
|
cache.sync_committees[period] = res
|
|
|
|
|
|
|
|
res
|
2022-03-15 08:24:55 +00:00
|
|
|
|
|
|
|
func dependent_root*(state: ForkyHashedBeaconState, epoch: Epoch): Eth2Digest =
|
|
|
|
## Return the root of the last block that contributed to the shuffling in the
|
|
|
|
## given epoch
|
|
|
|
if epoch > state.data.slot.epoch:
|
|
|
|
state.latest_block_root
|
|
|
|
elif epoch == Epoch(0):
|
|
|
|
if state.data.slot == Slot(0):
|
|
|
|
state.latest_block_root
|
|
|
|
else:
|
|
|
|
state.data.get_block_root_at_slot(Slot(0))
|
|
|
|
else:
|
|
|
|
let dependent_slot = epoch.start_slot - 1
|
|
|
|
if state.data.slot <= dependent_slot + SLOTS_PER_HISTORICAL_ROOT:
|
|
|
|
state.data.get_block_root_at_slot(epoch.start_slot - 1)
|
|
|
|
else:
|
|
|
|
Eth2Digest() # "don't know"
|
|
|
|
|
|
|
|
func proposer_dependent_root*(state: ForkyHashedBeaconState): Eth2Digest =
|
|
|
|
state.dependent_root(state.data.slot.epoch)
|
|
|
|
|
|
|
|
func attester_dependent_root*(state: ForkyHashedBeaconState): Eth2Digest =
|
2022-09-19 10:28:52 +00:00
|
|
|
state.dependent_root(state.data.slot.epoch.get_previous_epoch)
|
2022-03-16 07:20:40 +00:00
|
|
|
|
2022-03-16 15:00:18 +00:00
|
|
|
func latest_block_id*(state: ForkyHashedBeaconState): BlockId =
|
|
|
|
## Block id of the latest block applied to this state
|
|
|
|
BlockId(
|
|
|
|
root: state.latest_block_root,
|
|
|
|
slot: state.data.latest_block_header.slot)
|
|
|
|
|
|
|
|
func latest_block_id*(state: ForkedHashedBeaconState): BlockId =
|
|
|
|
## Block id of the latest block applied to this state
|
2022-09-13 11:53:12 +00:00
|
|
|
withState(state): forkyState.latest_block_id()
|
2022-03-16 15:00:18 +00:00
|
|
|
|
2022-03-16 07:20:40 +00:00
|
|
|
func matches_block*(
|
|
|
|
state: ForkyHashedBeaconState, block_root: Eth2Digest): bool =
|
|
|
|
## Return true iff the latest block applied to this state matches the given
|
|
|
|
## `block_root`
|
|
|
|
block_root == state.latest_block_root
|
2022-03-16 15:00:18 +00:00
|
|
|
|
2022-03-16 07:20:40 +00:00
|
|
|
func matches_block*(
|
|
|
|
state: ForkedHashedBeaconState, block_root: Eth2Digest): bool =
|
2022-09-13 11:53:12 +00:00
|
|
|
withState(state): forkyState.matches_block(block_root)
|
2022-03-16 07:20:40 +00:00
|
|
|
|
|
|
|
func matches_block_slot*(
|
|
|
|
state: ForkyHashedBeaconState, block_root: Eth2Digest, slot: Slot): bool =
|
|
|
|
## Return true iff the latest block applied to this state matches the given
|
|
|
|
## `block_root` and the state slot has been advanced to the given slot
|
|
|
|
slot == state.data.slot and block_root == state.latest_block_root
|
|
|
|
func matches_block_slot*(
|
|
|
|
state: ForkedHashedBeaconState, block_root: Eth2Digest, slot: Slot): bool =
|
2022-09-13 11:53:12 +00:00
|
|
|
withState(state): forkyState.matches_block_slot(block_root, slot)
|
2022-03-16 07:20:40 +00:00
|
|
|
|
|
|
|
func can_advance_slots*(
|
|
|
|
state: ForkyHashedBeaconState, block_root: Eth2Digest, target_slot: Slot): bool =
|
|
|
|
## Return true iff we can reach the given block/slot combination simply by
|
2022-11-10 10:44:47 +00:00
|
|
|
## advancing 0 or more slots
|
2022-03-16 07:20:40 +00:00
|
|
|
target_slot >= state.data.slot and block_root == state.latest_block_root
|
|
|
|
func can_advance_slots*(
|
|
|
|
state: ForkedHashedBeaconState, block_root: Eth2Digest, target_slot: Slot): bool =
|
2022-09-13 11:53:12 +00:00
|
|
|
withState(state): forkyState.can_advance_slots(block_root, target_slot)
|