2019-06-28 13:44:44 +00:00
|
|
|
# beacon_chain
|
2021-01-26 11:52:00 +00:00
|
|
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
2019-06-28 13:44:44 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
2019-06-28 13:44:44 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
|
|
|
# State transition - block processing, as described in
|
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
|
|
|
|
#
|
|
|
|
# The entry point is `process_block` which is at the bottom of this file.
|
|
|
|
#
|
2020-11-04 21:52:47 +00:00
|
|
|
# General notes about the code:
|
2019-06-28 13:44:44 +00:00
|
|
|
# * Weird styling - the sections taken from the spec use python styling while
|
|
|
|
# the others use NEP-1 - helps grepping identifiers in spec
|
2020-11-04 21:52:47 +00:00
|
|
|
# * When updating the code, add TODO sections to mark where there are clear
|
|
|
|
# improvements to be made - other than that, keep things similar to spec unless
|
|
|
|
# motivated by security or performance considerations
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-04-22 05:53:02 +00:00
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
2019-12-04 10:49:59 +00:00
|
|
|
import
|
2021-01-26 11:52:00 +00:00
|
|
|
std/[algorithm, intsets, options, sequtils],
|
2020-11-27 22:16:13 +00:00
|
|
|
chronicles,
|
2020-06-03 13:52:02 +00:00
|
|
|
../extras, ../ssz/merkleization, metrics,
|
2020-06-16 05:45:04 +00:00
|
|
|
./beaconstate, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
|
2020-07-07 23:02:14 +00:00
|
|
|
./signatures, ./presets,
|
2019-12-20 16:14:43 +00:00
|
|
|
../../nbench/bench_lab
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#block-header
|
2020-07-03 17:03:14 +00:00
|
|
|
func process_block_header*(
|
2020-06-25 10:23:10 +00:00
|
|
|
state: var BeaconState, blck: SomeBeaconBlock, flags: UpdateFlags,
|
2020-07-03 17:03:14 +00:00
|
|
|
stateCache: var StateCache): Result[void, cstring] {.nbench.} =
|
2019-06-28 13:44:44 +00:00
|
|
|
# Verify that the slots match
|
|
|
|
if not (blck.slot == state.slot):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_block_header: slot mismatch")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-05-19 14:37:29 +00:00
|
|
|
# Verify that the block is newer than latest block header
|
|
|
|
if not (blck.slot > state.latest_block_header.slot):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_block_header: block not newer than latest block header")
|
2020-05-19 14:37:29 +00:00
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Verify that proposer index is the correct index
|
|
|
|
let proposer_index = get_beacon_proposer_index(state, stateCache)
|
|
|
|
if proposer_index.isNone:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_block_header: proposer missing")
|
2020-03-14 21:54:45 +00:00
|
|
|
|
|
|
|
if not (blck.proposer_index.ValidatorIndex == proposer_index.get):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_block_header: proposer index incorrect")
|
2020-03-14 21:54:45 +00:00
|
|
|
|
2019-06-28 13:44:44 +00:00
|
|
|
# Verify that the parent matches
|
2020-06-18 05:56:47 +00:00
|
|
|
if not (blck.parent_root == hash_tree_root(state.latest_block_header)):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_block_header: previous block root mismatch")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-09-01 07:49:55 +00:00
|
|
|
# Verify proposer is not slashed
|
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 state.validators.asSeq()[blck.proposer_index].slashed:
|
2020-09-01 07:49:55 +00:00
|
|
|
return err("process_block_header: proposer slashed")
|
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Cache current block as the new latest block
|
2019-06-28 13:44:44 +00:00
|
|
|
state.latest_block_header = BeaconBlockHeader(
|
|
|
|
slot: blck.slot,
|
2020-03-14 21:54:45 +00:00
|
|
|
proposer_index: blck.proposer_index,
|
2019-06-28 13:44:44 +00:00
|
|
|
parent_root: blck.parent_root,
|
2019-07-15 12:57:18 +00:00
|
|
|
# state_root: zeroed, overwritten in the next `process_slot` call
|
2019-06-28 13:44:44 +00:00
|
|
|
body_root: hash_tree_root(blck.body),
|
|
|
|
)
|
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
func `xor`[T: array](a, b: T): T =
|
2020-05-28 16:34:59 +00:00
|
|
|
for i in 0..<result.len:
|
|
|
|
result[i] = a[i] xor b[i]
|
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#randao
|
2019-09-04 13:57:18 +00:00
|
|
|
proc process_randao(
|
2020-06-25 10:23:10 +00:00
|
|
|
state: var BeaconState, body: SomeBeaconBlockBody, flags: UpdateFlags,
|
2021-04-08 10:11:04 +00:00
|
|
|
stateCache: var StateCache): Result[void, cstring] {.nbench.} =
|
2019-06-28 13:44:44 +00:00
|
|
|
let
|
|
|
|
proposer_index = get_beacon_proposer_index(state, stateCache)
|
2019-12-04 10:49:59 +00:00
|
|
|
|
|
|
|
if proposer_index.isNone:
|
2021-04-08 10:11:04 +00:00
|
|
|
return err("process_randao: proposer index missing, probably along with any active validators")
|
2019-12-04 10:49:59 +00:00
|
|
|
|
2020-05-26 05:04:24 +00:00
|
|
|
# Verify RANDAO reveal
|
2020-06-16 05:45:04 +00:00
|
|
|
let
|
|
|
|
epoch = state.get_current_epoch()
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
if skipBLSValidation notin flags:
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
let proposer_pubkey = state.validators.asSeq()[proposer_index.get].pubkey
|
2020-06-16 05:45:04 +00:00
|
|
|
|
|
|
|
if not verify_epoch_signature(
|
|
|
|
state.fork, state.genesis_validators_root, epoch, proposer_pubkey,
|
|
|
|
body.randao_reveal):
|
2021-04-08 10:11:04 +00:00
|
|
|
|
|
|
|
return err("process_randao: invalid epoch signature")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
|
|
|
# Mix it in
|
|
|
|
let
|
2019-09-04 13:57:18 +00:00
|
|
|
mix = get_randao_mix(state, epoch)
|
2020-06-16 12:16:43 +00:00
|
|
|
rr = eth2digest(body.randao_reveal.toRaw()).data
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-05-28 16:34:59 +00:00
|
|
|
state.randao_mixes[epoch mod EPOCHS_PER_HISTORICAL_VECTOR].data =
|
|
|
|
mix.data xor rr
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-04-08 10:11:04 +00:00
|
|
|
ok()
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#eth1-data
|
2021-04-08 10:11:04 +00:00
|
|
|
func process_eth1_data(state: var BeaconState, body: SomeBeaconBlockBody): Result[void, cstring] {.nbench.}=
|
|
|
|
if not state.eth1_data_votes.add body.eth1_data:
|
|
|
|
# Count is reset in process_final_updates, so this should never happen
|
|
|
|
return err("process_eth1_data: no more room for eth1 data")
|
2020-05-28 16:34:59 +00:00
|
|
|
|
2020-07-26 18:55:48 +00:00
|
|
|
if state.eth1_data_votes.asSeq.count(body.eth1_data).uint64 * 2 >
|
|
|
|
SLOTS_PER_ETH1_VOTING_PERIOD:
|
2019-07-01 09:42:37 +00:00
|
|
|
state.eth1_data = body.eth1_data
|
2021-04-08 10:11:04 +00:00
|
|
|
ok()
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_slashable_validator
|
2019-06-28 13:44:44 +00:00
|
|
|
func is_slashable_validator(validator: Validator, epoch: Epoch): bool =
|
|
|
|
# Check if ``validator`` is slashable.
|
|
|
|
(not validator.slashed) and
|
|
|
|
(validator.activation_epoch <= epoch) and
|
|
|
|
(epoch < validator.withdrawable_epoch)
|
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#proposer-slashings
|
2020-09-24 17:05:49 +00:00
|
|
|
proc check_proposer_slashing*(
|
2021-01-25 18:45:48 +00:00
|
|
|
state: var BeaconState, proposer_slashing: SomeProposerSlashing,
|
2020-12-16 14:36:02 +00:00
|
|
|
flags: UpdateFlags):
|
2020-07-03 17:03:14 +00:00
|
|
|
Result[void, cstring] {.nbench.} =
|
2020-03-14 21:54:45 +00:00
|
|
|
|
|
|
|
let
|
|
|
|
header_1 = proposer_slashing.signed_header_1.message
|
|
|
|
header_2 = proposer_slashing.signed_header_2.message
|
|
|
|
|
|
|
|
# Not from spec
|
2020-07-26 18:55:48 +00:00
|
|
|
if header_1.proposer_index >= state.validators.lenu64:
|
2020-09-24 17:05:49 +00:00
|
|
|
return err("check_proposer_slashing: invalid proposer index")
|
2019-09-11 07:50:07 +00:00
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Verify header slots match
|
|
|
|
if not (header_1.slot == header_2.slot):
|
2020-09-24 17:05:49 +00:00
|
|
|
return err("check_proposer_slashing: slot mismatch")
|
2019-09-10 15:29:46 +00:00
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Verify header proposer indices match
|
|
|
|
if not (header_1.proposer_index == header_2.proposer_index):
|
2020-09-24 17:05:49 +00:00
|
|
|
return err("check_proposer_slashing: proposer indices mismatch")
|
2020-03-14 21:54:45 +00:00
|
|
|
|
|
|
|
# Verify the headers are different
|
|
|
|
if not (header_1 != header_2):
|
2020-09-24 17:05:49 +00:00
|
|
|
return err("check_proposer_slashing: headers not different")
|
2019-09-10 15:29:46 +00:00
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Verify the proposer is slashable
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
let proposer = unsafeAddr state.validators.asSeq()[header_1.proposer_index]
|
|
|
|
if not is_slashable_validator(proposer[], get_current_epoch(state)):
|
2020-09-24 17:05:49 +00:00
|
|
|
return err("check_proposer_slashing: slashed proposer")
|
2019-09-10 15:29:46 +00:00
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Verify signatures
|
2020-03-05 12:52:10 +00:00
|
|
|
if skipBlsValidation notin flags:
|
2020-09-24 17:05:49 +00:00
|
|
|
for signed_header in [proposer_slashing.signed_header_1,
|
2019-12-16 18:08:50 +00:00
|
|
|
proposer_slashing.signed_header_2]:
|
2020-06-16 05:45:04 +00:00
|
|
|
if not verify_block_signature(
|
|
|
|
state.fork, state.genesis_validators_root, signed_header.message.slot,
|
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
|
|
|
signed_header.message, proposer[].pubkey, signed_header.signature):
|
2020-09-24 17:05:49 +00:00
|
|
|
return err("check_proposer_slashing: invalid signature")
|
2019-09-10 15:29:46 +00:00
|
|
|
|
2020-09-24 17:05:49 +00:00
|
|
|
ok()
|
2019-09-10 15:29:46 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#proposer-slashings
|
2020-09-24 17:05:49 +00:00
|
|
|
proc process_proposer_slashing*(
|
2021-01-25 18:45:48 +00:00
|
|
|
state: var BeaconState, proposer_slashing: SomeProposerSlashing,
|
2020-09-24 17:05:49 +00:00
|
|
|
flags: UpdateFlags, cache: var StateCache):
|
|
|
|
Result[void, cstring] {.nbench.} =
|
2020-12-16 14:36:02 +00:00
|
|
|
? check_proposer_slashing(state, proposer_slashing, flags)
|
2020-09-24 17:05:49 +00:00
|
|
|
slash_validator(
|
|
|
|
state,
|
|
|
|
proposer_slashing.signed_header_1.message.proposer_index.ValidatorIndex,
|
|
|
|
cache)
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-09-10 15:29:46 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_slashable_attestation_data
|
2020-09-14 14:26:31 +00:00
|
|
|
func is_slashable_attestation_data*(
|
2019-06-28 13:44:44 +00:00
|
|
|
data_1: AttestationData, data_2: AttestationData): bool =
|
|
|
|
## Check if ``data_1`` and ``data_2`` are slashable according to Casper FFG
|
|
|
|
## rules.
|
|
|
|
|
|
|
|
# Double vote
|
2019-07-02 21:14:55 +00:00
|
|
|
(data_1 != data_2 and data_1.target.epoch == data_2.target.epoch) or
|
2019-06-28 13:44:44 +00:00
|
|
|
# Surround vote
|
2019-07-02 21:14:55 +00:00
|
|
|
(data_1.source.epoch < data_2.source.epoch and
|
|
|
|
data_2.target.epoch < data_1.target.epoch)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#attester-slashings
|
2020-09-24 17:05:49 +00:00
|
|
|
proc check_attester_slashing*(
|
2019-09-10 22:03:06 +00:00
|
|
|
state: var BeaconState,
|
2021-01-25 18:45:48 +00:00
|
|
|
attester_slashing: SomeAttesterSlashing,
|
2020-12-16 14:36:02 +00:00
|
|
|
flags: UpdateFlags
|
2020-09-24 17:05:49 +00:00
|
|
|
): Result[seq[ValidatorIndex], cstring] {.nbench.} =
|
2020-07-03 17:03:14 +00:00
|
|
|
let
|
|
|
|
attestation_1 = attester_slashing.attestation_1
|
|
|
|
attestation_2 = attester_slashing.attestation_2
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
if not is_slashable_attestation_data(
|
|
|
|
attestation_1.data, attestation_2.data):
|
|
|
|
return err("Attester slashing: surround or double vote check failed")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-13 13:47:06 +00:00
|
|
|
if not is_valid_indexed_attestation(state, attestation_1, flags).isOk():
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Attester slashing: invalid attestation 1")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-08-13 13:47:06 +00:00
|
|
|
if not is_valid_indexed_attestation(state, attestation_2, flags).isOk():
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Attester slashing: invalid attestation 2")
|
|
|
|
|
2020-09-24 17:05:49 +00:00
|
|
|
var slashed_indices: seq[ValidatorIndex]
|
2020-07-03 17:03:14 +00:00
|
|
|
|
|
|
|
for index in sorted(toSeq(intersection(
|
2021-01-26 11:52:00 +00:00
|
|
|
toIntSet(attestation_1.attesting_indices.asSeq),
|
|
|
|
toIntSet(attestation_2.attesting_indices.asSeq)).items), system.cmp):
|
2020-07-03 17:03:14 +00:00
|
|
|
if is_slashable_validator(
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
state.validators.asSeq()[index], get_current_epoch(state)):
|
2020-09-24 17:05:49 +00:00
|
|
|
slashed_indices.add index.ValidatorIndex
|
|
|
|
if slashed_indices.len == 0:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Attester slashing: Trying to slash participant(s) twice")
|
2020-09-24 17:05:49 +00:00
|
|
|
|
|
|
|
ok slashed_indices
|
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#attester-slashings
|
2020-09-24 17:05:49 +00:00
|
|
|
proc process_attester_slashing*(
|
|
|
|
state: var BeaconState,
|
2021-01-25 18:45:48 +00:00
|
|
|
attester_slashing: SomeAttesterSlashing,
|
2020-09-24 17:05:49 +00:00
|
|
|
flags: UpdateFlags,
|
|
|
|
cache: var StateCache
|
|
|
|
): Result[void, cstring] {.nbench.} =
|
|
|
|
let attester_slashing_validity =
|
2020-12-16 14:36:02 +00:00
|
|
|
check_attester_slashing(state, attester_slashing, flags)
|
2020-09-24 17:05:49 +00:00
|
|
|
|
|
|
|
if attester_slashing_validity.isErr:
|
|
|
|
return err(attester_slashing_validity.error)
|
|
|
|
|
|
|
|
for index in attester_slashing_validity.value:
|
|
|
|
slash_validator(state, index, cache)
|
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-09-10 22:03:06 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#voluntary-exits
|
2020-09-24 17:05:49 +00:00
|
|
|
proc check_voluntary_exit*(
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
state: BeaconState,
|
2021-01-25 18:45:48 +00:00
|
|
|
signed_voluntary_exit: SomeSignedVoluntaryExit,
|
2020-12-16 14:36:02 +00:00
|
|
|
flags: UpdateFlags): Result[void, cstring] {.nbench.} =
|
2019-09-10 00:14:03 +00:00
|
|
|
|
2019-12-16 18:08:50 +00:00
|
|
|
let voluntary_exit = signed_voluntary_exit.message
|
|
|
|
|
2019-09-10 00:14:03 +00:00
|
|
|
# Not in spec. Check that validator_index is in range
|
2020-07-26 18:55:48 +00:00
|
|
|
if voluntary_exit.validator_index >= state.validators.lenu64:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Exit: invalid validator index")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
let validator = unsafeAddr state.validators.asSeq()[voluntary_exit.validator_index]
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2019-09-10 00:14:03 +00:00
|
|
|
# Verify the validator is active
|
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 not is_active_validator(validator[], get_current_epoch(state)):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Exit: validator not active")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-07-08 20:36:26 +00:00
|
|
|
# Verify exit has not been initiated
|
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 validator[].exit_epoch != FAR_FUTURE_EPOCH:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Exit: validator has exited")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
# Exits must specify an epoch when they become valid; they are not valid
|
|
|
|
# before then
|
2019-12-16 18:08:50 +00:00
|
|
|
if not (get_current_epoch(state) >= voluntary_exit.epoch):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Exit: exit epoch not passed")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2019-09-10 00:14:03 +00:00
|
|
|
# Verify the validator has been active long enough
|
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 not (get_current_epoch(state) >= validator[].activation_epoch +
|
2020-06-29 18:08:58 +00:00
|
|
|
SHARD_COMMITTEE_PERIOD):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Exit: not in validator set long enough")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2019-09-10 00:14:03 +00:00
|
|
|
# Verify signature
|
2020-03-05 12:52:10 +00:00
|
|
|
if skipBlsValidation notin flags:
|
2020-06-16 05:45:04 +00:00
|
|
|
if not verify_voluntary_exit_signature(
|
|
|
|
state.fork, state.genesis_validators_root, voluntary_exit,
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
validator[].pubkey, signed_voluntary_exit.signature):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("Exit: invalid signature")
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2019-09-10 00:14:03 +00:00
|
|
|
# Initiate exit
|
2020-09-24 17:05:49 +00:00
|
|
|
debug "Exit: checking voluntary exit (validator_leaving)",
|
2019-12-16 18:08:50 +00:00
|
|
|
index = voluntary_exit.validator_index,
|
2019-11-25 08:22:16 +00:00
|
|
|
num_validators = state.validators.len,
|
2019-12-16 18:08:50 +00:00
|
|
|
epoch = voluntary_exit.epoch,
|
2019-11-25 08:22:16 +00:00
|
|
|
current_epoch = get_current_epoch(state),
|
performance fixes (#2259)
* performance fixes
* don't mark tree cache as dirty on read-only List accesses
* store only blob in memory for keys and signatures, parse blob lazily
* compare public keys by blob instead of parsing / converting to raw
* compare Eth2Digest using non-constant-time comparison
* avoid some unnecessary validator copying
This branch will in particular speed up deposit processing which has
been slowing down block replay.
Pre (mainnet, 1600 blocks):
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3450.269, 0.000, 3450.269, 3450.269, 1, Initialize DB
0.417, 0.822, 0.036, 21.098, 1400, Load block from database
16.521, 0.000, 16.521, 16.521, 1, Load state from database
27.906, 50.846, 8.104, 1507.633, 1350, Apply block
52.617, 37.029, 20.640, 135.938, 50, Apply epoch block
```
Post:
```
3502.715, 0.000, 3502.715, 3502.715, 1, Initialize DB
0.080, 0.560, 0.035, 21.015, 1400, Load block from database
17.595, 0.000, 17.595, 17.595, 1, Load state from database
15.706, 11.028, 8.300, 107.537, 1350, Apply block
33.217, 12.622, 17.331, 60.580, 50, Apply epoch block
```
* more perf fixes
* load EpochRef cache into StateCache more aggressively
* point out security concern with public key cache
* reuse proposer index from state when processing block
* avoid genericAssign in a few more places
* don't parse key when signature is unparseable
* fix `==` overload for Eth2Digest
* preallocate validator list when getting active validators
* speed up proposer index calculation a little bit
* reuse cache when replaying blocks in ncli_db
* avoid a few more copying loops
```
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3279.158, 0.000, 3279.158, 3279.158, 1, Initialize DB
0.072, 0.357, 0.035, 13.400, 1400, Load block from database
17.295, 0.000, 17.295, 17.295, 1, Load state from database
5.918, 9.896, 0.198, 98.028, 1350, Apply block
15.888, 10.951, 7.902, 39.535, 50, Apply epoch block
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
* clear full balance cache before processing rewards and penalties
```
All time are ms
Average, StdDev, Min, Max, Samples, Test
Validation is turned off meaning that no BLS operations are performed
3947.901, 0.000, 3947.901, 3947.901, 1, Initialize DB
0.124, 0.506, 0.026, 202.370, 363345, Load block from database
97.614, 0.000, 97.614, 97.614, 1, Load state from database
0.186, 0.188, 0.012, 99.561, 357262, Advance slot, non-epoch
14.161, 5.966, 1.099, 395.511, 11524, Advance slot, epoch
1.372, 4.170, 0.017, 276.401, 363345, Apply block, no slot processing
0.000, 0.000, 0.000, 0.000, 0, Database block store
```
2021-01-25 12:04:18 +00:00
|
|
|
validator_slashed = validator[].slashed,
|
|
|
|
validator_withdrawable_epoch = validator[].withdrawable_epoch,
|
|
|
|
validator_exit_epoch = validator[].exit_epoch,
|
|
|
|
validator_effective_balance = validator[].effective_balance
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#voluntary-exits
|
2020-09-24 17:05:49 +00:00
|
|
|
proc process_voluntary_exit*(
|
|
|
|
state: var BeaconState,
|
2021-01-25 18:45:48 +00:00
|
|
|
signed_voluntary_exit: SomeSignedVoluntaryExit,
|
2020-09-24 17:05:49 +00:00
|
|
|
flags: UpdateFlags,
|
|
|
|
cache: var StateCache): Result[void, cstring] {.nbench.} =
|
2020-12-16 14:36:02 +00:00
|
|
|
? check_voluntary_exit(state, signed_voluntary_exit, flags)
|
2020-09-24 17:05:49 +00:00
|
|
|
initiate_validator_exit(
|
|
|
|
state, signed_voluntary_exit.message.validator_index.ValidatorIndex, cache)
|
|
|
|
ok()
|
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#operations
|
2020-07-07 23:02:14 +00:00
|
|
|
proc process_operations(preset: RuntimePreset,
|
|
|
|
state: var BeaconState,
|
|
|
|
body: SomeBeaconBlockBody,
|
|
|
|
flags: UpdateFlags,
|
2020-08-14 12:42:59 +00:00
|
|
|
cache: var StateCache): Result[void, cstring] {.nbench.} =
|
2020-05-22 15:52:07 +00:00
|
|
|
# Verify that outstanding deposits are processed up to the maximum number of
|
|
|
|
# deposits
|
|
|
|
let
|
|
|
|
req_deposits = min(MAX_DEPOSITS,
|
2020-07-13 14:44:58 +00:00
|
|
|
state.eth1_data.deposit_count - state.eth1_deposit_index)
|
2020-08-21 13:34:14 +00:00
|
|
|
if state.eth1_data.deposit_count < state.eth1_deposit_index or
|
|
|
|
body.deposits.lenu64 != req_deposits:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("incorrect number of deposits")
|
2020-05-22 15:52:07 +00:00
|
|
|
|
2020-05-22 17:00:58 +00:00
|
|
|
template for_ops(operations: auto, fn: auto) =
|
2020-05-22 15:52:07 +00:00
|
|
|
for operation in operations:
|
2020-08-14 12:42:59 +00:00
|
|
|
let res = fn(state, operation, flags, cache)
|
2020-07-03 17:03:14 +00:00
|
|
|
if res.isErr:
|
|
|
|
return res
|
2020-05-22 15:52:07 +00:00
|
|
|
|
2020-08-14 12:42:59 +00:00
|
|
|
for_ops(body.proposer_slashings, process_proposer_slashing)
|
|
|
|
for_ops(body.attester_slashings, process_attester_slashing)
|
|
|
|
for_ops(body.attestations, process_attestation)
|
2020-07-07 23:02:14 +00:00
|
|
|
|
|
|
|
for deposit in body.deposits:
|
2020-07-08 12:36:03 +00:00
|
|
|
let res = process_deposit(preset, state, deposit, flags)
|
|
|
|
if res.isErr:
|
|
|
|
return res
|
2020-07-07 23:02:14 +00:00
|
|
|
|
2020-05-22 17:00:58 +00:00
|
|
|
for_ops(body.voluntary_exits, process_voluntary_exit)
|
2020-05-22 15:52:07 +00:00
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-09-10 00:14:03 +00:00
|
|
|
|
2021-02-25 13:37:22 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#block-processing
|
2020-03-15 13:01:37 +00:00
|
|
|
proc process_block*(
|
2020-07-07 23:02:14 +00:00
|
|
|
preset: RuntimePreset,
|
2020-06-25 10:23:10 +00:00
|
|
|
state: var BeaconState, blck: SomeBeaconBlock, flags: UpdateFlags,
|
2021-04-08 10:11:04 +00:00
|
|
|
cache: var StateCache): Result[void, cstring] {.nbench.}=
|
2019-06-28 13:44:44 +00:00
|
|
|
## When there's a new block, we need to verify that the block is sane and
|
2020-11-02 17:34:23 +00:00
|
|
|
## update the state accordingly - the state is left in an unknown state when
|
|
|
|
## block application fails (!)
|
2019-10-21 08:11:54 +00:00
|
|
|
|
2021-04-08 10:11:04 +00:00
|
|
|
? process_block_header(state, blck, flags, cache)
|
|
|
|
? process_randao(state, blck.body, flags, cache)
|
|
|
|
? process_eth1_data(state, blck.body)
|
|
|
|
? process_operations(preset, state, blck.body, flags, cache)
|
2019-06-28 13:44:44 +00:00
|
|
|
|
2020-12-02 12:23:10 +00:00
|
|
|
ok()
|