2018-08-21 16:21:45 +00:00
# beacon_chain
2024-01-06 14:26:56 +00:00
# Copyright (c) 2018-2024 Status Research & Development GmbH
2018-08-21 16:21:45 +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-08-21 16:21:45 +00:00
# at your option. This file may not be copied, modified, or distributed except according to those terms.
2024-02-18 01:16:49 +00:00
{. push raises : [ ] . }
2018-12-04 18:45:30 +00:00
# State transition, as described in
2024-02-22 02:42:57 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
2018-08-21 16:21:45 +00:00
#
2020-11-04 21:52:47 +00:00
# The entry point is `state_transition` which is at the bottom of the file!
2018-12-04 18:45:30 +00:00
#
2020-11-04 21:52:47 +00:00
# General notes about the code:
2018-12-04 18:45:30 +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
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
#
# Performance notes:
# * The state transition is used in two contexts: to verify that incoming blocks
# are correct and to replay existing blocks from database. Incoming blocks
# are processed one-by-one while replay happens multiple blocks at a time.
# * Although signature verification is the slowest operation in the state
# state transition, we skip it during replay - this is also when we repeatedly
# call the state transition, making the non-signature part of the code
# important from a performance point of view.
# * It's important to start with a prefilled cache - generating the shuffled
# list of active validators is generally very slow.
# * Throughout, the code is affected by inefficient for loop codegen, meaning
# that we have to iterate over indices and pick out the value manually:
# https://github.com/nim-lang/Nim/issues/14421
# * Throughout, we're affected by inefficient `let` borrowing, meaning we
# often have to take the address of a sequence item due to the above - look
# for `let ... = unsafeAddr sequence[idx]`
# * Throughout, we're affected by the overloading rules that prefer a `var`
# overload to a non-var overload - look for `asSeq()` - when the `var`
# overload is used, the hash tree cache is cleared, which, aside from being
2023-08-07 10:06:47 +00:00
# slow itself, causes additional processing to recalculate the Merkle tree.
2018-08-21 16:21:45 +00:00
2018-09-26 16:26:39 +00:00
import
2020-04-11 17:41:50 +00:00
chronicles ,
2024-01-16 22:37:14 +00:00
results ,
2021-08-12 13:08:20 +00:00
.. / extras ,
" . " / [
2021-08-18 18:57:58 +00:00
beaconstate , eth2_merkleization , forks , helpers , signatures ,
2021-12-03 14:46:56 +00:00
state_transition_block , state_transition_epoch , validator ]
2018-12-13 16:00:55 +00:00
2024-03-11 14:18:50 +00:00
export results , extras , state_transition_block
2021-05-28 15:25:58 +00:00
2023-08-07 16:02:08 +00:00
logScope :
topics = " state_transition "
2024-01-20 11:19:47 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
2021-06-03 09:42:25 +00:00
proc verify_block_signature (
2022-01-17 11:19:58 +00:00
state : ForkyBeaconState , signed_block : SomeForkySignedBeaconBlock ) :
Result [ void , cstring ] =
2020-06-16 05:45:04 +00:00
let
proposer_index = signed_block . message . proposer_index
2020-07-26 18:55:48 +00:00
if proposer_index > = state . validators . lenu64 :
2022-01-17 11:19:58 +00:00
return err ( " block: invalid proposer index " )
2020-04-09 09:41:02 +00:00
2020-06-16 05:45:04 +00:00
if not verify_block_signature (
state . fork , state . genesis_validators_root , signed_block . message . slot ,
2021-11-05 05:50:01 +00:00
signed_block . root , state . validators [ proposer_index ] . pubkey ,
2020-06-16 05:45:04 +00:00
signed_block . signature ) :
2022-01-17 11:19:58 +00:00
return err ( " block: signature verification failed " )
2020-04-09 09:41:02 +00:00
2022-01-17 11:19:58 +00:00
ok ( )
2020-04-09 09:41:02 +00:00
2024-04-17 03:51:16 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
2022-02-17 11:53:55 +00:00
func verifyStateRoot (
2023-05-10 14:04:48 +00:00
state : ForkyBeaconState ,
blck : ForkyBeaconBlock | ForkySigVerifiedBeaconBlock ) :
2022-01-17 11:19:58 +00:00
Result [ void , cstring ] =
2019-09-05 19:52:34 +00:00
# This is inlined in state_transition(...) in spec.
2019-03-25 16:46:31 +00:00
let state_root = hash_tree_root ( state )
2018-12-21 22:37:46 +00:00
if state_root ! = blck . state_root :
2022-01-17 11:19:58 +00:00
err ( " block: state root verification failed " )
2018-12-21 22:37:46 +00:00
else :
2022-01-17 11:19:58 +00:00
ok ( )
2018-12-21 22:37:46 +00:00
2022-01-17 11:19:58 +00:00
func verifyStateRoot (
state : ForkyBeaconState , blck : ForkyTrustedBeaconBlock ) :
Result [ void , cstring ] =
2020-06-25 10:23:10 +00:00
# This is inlined in state_transition(...) in spec.
2022-01-17 11:19:58 +00:00
ok ( )
2021-06-04 10:38:00 +00:00
2020-04-26 19:13:33 +00:00
type
2023-08-25 09:29:07 +00:00
RollbackProc * = proc ( ) {. gcsafe , noSideEffect , raises : [ ] . }
2022-11-11 14:37:43 +00:00
RollbackHashedProc * [ T ] =
2023-08-25 09:29:07 +00:00
proc ( state : var T ) {. gcsafe , noSideEffect , raises : [ ] . }
2022-01-28 14:24:37 +00:00
RollbackForkedHashedProc * = RollbackHashedProc [ ForkedHashedBeaconState ]
2020-04-26 19:13:33 +00:00
2021-06-29 15:09:29 +00:00
func noRollback * ( ) =
trace " Skipping rollback of broken state "
2020-04-26 19:13:33 +00:00
2019-07-15 21:10:40 +00:00
# Hashed-state transition functions
# ---------------------------------------------------------------
2019-05-04 14:10: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#beacon-chain-state-transition-function
2021-05-05 06:54:21 +00:00
func process_slot * (
2021-12-03 14:46:56 +00:00
state : var ForkyBeaconState , pre_state_root : Eth2Digest ) =
2021-05-05 06:54:21 +00:00
# `process_slot` is the first stage of per-slot processing - it is run for
# every slot, including epoch slots - it does not however update the slot
# number! `pre_state_root` refers to the state root of the incoming
# state before any slot processing has been done.
2019-06-14 07:50:14 +00:00
# Cache state root
2021-05-05 06:54:21 +00:00
state . state_roots [ state . slot mod SLOTS_PER_HISTORICAL_ROOT ] = pre_state_root
2019-05-04 14:10:45 +00:00
2019-06-14 07:50:14 +00:00
# Cache latest block header state root
2021-05-05 06:54:21 +00:00
if state . latest_block_header . state_root = = ZERO_HASH :
state . latest_block_header . state_root = pre_state_root
2019-05-04 14:10:45 +00:00
2019-06-14 07:50:14 +00:00
# Cache block root
2021-05-05 06:54:21 +00:00
state . block_roots [ state . slot mod SLOTS_PER_HISTORICAL_ROOT ] =
hash_tree_root ( state . latest_block_header )
2019-05-04 14:10:45 +00:00
2020-09-08 11:32:43 +00:00
func clear_epoch_from_cache ( cache : var StateCache , epoch : Epoch ) =
2022-12-19 12:01:49 +00:00
cache . total_active_balance . del epoch
2020-09-08 11:32:43 +00:00
cache . shuffled_active_validator_indices . del epoch
2022-01-11 10:01:54 +00:00
for slot in epoch . slots ( ) :
cache . beacon_proposer_indices . del slot
2020-09-08 11:32:43 +00:00
2024-01-20 11:19:47 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
2020-10-15 12:28:44 +00:00
proc advance_slot (
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 : RuntimeConfig ,
2021-11-05 07:34:34 +00:00
state : var ForkyBeaconState , previous_slot_state_root : Eth2Digest ,
2022-05-25 13:49:29 +00:00
flags : UpdateFlags , cache : var StateCache , info : var ForkyEpochInfo ) :
Result [ void , cstring ] =
2021-05-05 06:54:21 +00:00
# Do the per-slot and potentially the per-epoch processing, then bump the
# slot number - we've now arrived at the slot state on top of which a block
# optionally can be applied.
process_slot ( state , previous_slot_state_root )
2021-10-13 14:24:36 +00:00
info . clear ( )
2021-05-07 11:36:21 +00:00
2023-05-10 14:04:48 +00:00
# Process epoch on the start slot of the next epoch
2022-01-11 10:01:54 +00:00
let is_epoch_transition = ( state . slot + 1 ) . is_epoch
2020-05-03 17:44:04 +00:00
if is_epoch_transition :
# Note: Genesis epoch = 0, no need to test if before Genesis
2022-05-25 13:49:29 +00:00
? process_epoch ( cfg , state , flags , cache , info )
2022-01-11 10:01:54 +00:00
clear_epoch_from_cache ( cache , ( state . slot + 1 ) . epoch )
2020-09-07 15:04:33 +00:00
2021-05-05 06:54:21 +00:00
state . slot + = 1
2020-05-03 17:44:04 +00:00
2022-05-25 13:49:29 +00:00
ok ( )
2021-06-03 09:42:25 +00:00
func noRollback * ( state : var phase0 . HashedBeaconState ) =
2021-06-21 08:35:24 +00:00
trace " Skipping rollback of broken phase 0 state "
func noRollback * ( state : var altair . HashedBeaconState ) =
trace " Skipping rollback of broken Altair state "
2019-05-04 14:10:45 +00:00
2022-01-06 11:25:35 +00:00
func noRollback * ( state : var bellatrix . HashedBeaconState ) =
trace " Skipping rollback of broken Bellatrix state "
2021-09-30 01:07:24 +00:00
2022-11-11 10:17:27 +00:00
func noRollback * ( state : var capella . HashedBeaconState ) =
trace " Skipping rollback of broken Capella state "
2023-02-23 18:06:57 +00:00
func noRollback * ( state : var deneb . HashedBeaconState ) =
2023-03-11 00:28:19 +00:00
trace " Skipping rollback of broken Deneb state "
2022-12-09 21:39:11 +00:00
2024-02-26 02:38:21 +00:00
func noRollback * ( state : var electra . HashedBeaconState ) =
trace " Skipping rollback of broken Electra state "
2022-02-17 11:53:55 +00:00
func maybeUpgradeStateToAltair (
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 : RuntimeConfig , state : var ForkedHashedBeaconState ) =
2021-06-11 17:51:46 +00:00
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
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 getStateField ( state , slot ) . epoch = = cfg . ALTAIR_FORK_EPOCH and
2023-01-28 19:53:41 +00:00
state . kind = = ConsensusFork . Phase0 :
2022-02-20 20:13:06 +00:00
let newState = upgrade_to_altair ( cfg , state . phase0Data . data )
2021-06-11 17:51:46 +00:00
state = ( ref ForkedHashedBeaconState ) (
2023-01-28 19:53:41 +00:00
kind : ConsensusFork . Altair ,
2021-10-18 16:37:27 +00:00
altairData : altair . HashedBeaconState (
2021-06-11 17:51:46 +00:00
root : hash_tree_root ( newState [ ] ) , data : newState [ ] ) ) [ ]
2021-06-04 10:38:00 +00:00
2022-01-04 09:45:38 +00:00
func maybeUpgradeStateToBellatrix (
2021-09-30 01:07:24 +00:00
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ) =
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
2022-02-02 13:06:55 +00:00
if getStateField ( state , slot ) . epoch = = cfg . BELLATRIX_FORK_EPOCH and
2023-01-28 19:53:41 +00:00
state . kind = = ConsensusFork . Altair :
2022-02-20 20:13:06 +00:00
let newState = upgrade_to_bellatrix ( cfg , state . altairData . data )
2021-09-30 01:07:24 +00:00
state = ( ref ForkedHashedBeaconState ) (
2023-01-28 19:53:41 +00:00
kind : ConsensusFork . Bellatrix ,
2022-01-24 16:23:13 +00:00
bellatrixData : bellatrix . HashedBeaconState (
2021-09-30 01:07:24 +00:00
root : hash_tree_root ( newState [ ] ) , data : newState [ ] ) ) [ ]
2022-11-09 12:28:34 +00:00
func maybeUpgradeStateToCapella (
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ) =
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
if getStateField ( state , slot ) . epoch = = cfg . CAPELLA_FORK_EPOCH and
2023-01-28 19:53:41 +00:00
state . kind = = ConsensusFork . Bellatrix :
2022-11-09 12:28:34 +00:00
let newState = upgrade_to_capella ( cfg , state . bellatrixData . data )
state = ( ref ForkedHashedBeaconState ) (
2023-01-28 19:53:41 +00:00
kind : ConsensusFork . Capella ,
2022-11-09 12:28:34 +00:00
capellaData : capella . HashedBeaconState (
root : hash_tree_root ( newState [ ] ) , data : newState [ ] ) ) [ ]
2023-03-11 14:28:55 +00:00
func maybeUpgradeStateToDeneb (
2022-12-08 02:07:41 +00:00
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ) =
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
2023-02-15 14:44:09 +00:00
if getStateField ( state , slot ) . epoch = = cfg . DENEB_FORK_EPOCH and
2023-01-28 19:53:41 +00:00
state . kind = = ConsensusFork . Capella :
2023-03-11 14:28:55 +00:00
let newState = upgrade_to_deneb ( cfg , state . capellaData . data )
2022-12-08 02:07:41 +00:00
state = ( ref ForkedHashedBeaconState ) (
2023-03-04 13:35:39 +00:00
kind : ConsensusFork . Deneb ,
2023-03-04 22:23:52 +00:00
denebData : deneb . HashedBeaconState (
2022-12-08 02:07:41 +00:00
root : hash_tree_root ( newState [ ] ) , data : newState [ ] ) ) [ ]
2024-04-07 07:58:11 +00:00
func maybeUpgradeStateToElectra (
2024-04-28 14:13:17 +00:00
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ,
cache : var StateCache ) =
2024-04-07 07:58:11 +00:00
# Both process_slots() and state_transition_block() call this, so only run it
# once by checking for existing fork.
if getStateField ( state , slot ) . epoch = = cfg . ELECTRA_FORK_EPOCH and
state . kind = = ConsensusFork . Deneb :
2024-04-28 14:13:17 +00:00
let newState = upgrade_to_electra ( cfg , state . denebData . data , cache )
2024-04-07 07:58:11 +00:00
state = ( ref ForkedHashedBeaconState ) (
kind : ConsensusFork . Electra ,
electraData : electra . HashedBeaconState (
root : hash_tree_root ( newState [ ] ) , data : newState [ ] ) ) [ ]
2022-02-17 11:53:55 +00:00
func maybeUpgradeState * (
2024-04-28 14:13:17 +00:00
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ,
cache : var StateCache ) =
2021-09-30 01:07:24 +00:00
cfg . maybeUpgradeStateToAltair ( state )
2022-01-04 09:45:38 +00:00
cfg . maybeUpgradeStateToBellatrix ( state )
2022-11-09 12:28:34 +00:00
cfg . maybeUpgradeStateToCapella ( state )
2023-03-11 14:28:55 +00:00
cfg . maybeUpgradeStateToDeneb ( state )
2024-04-28 14:13:17 +00:00
cfg . maybeUpgradeStateToElectra ( state , cache )
2021-09-30 01:07:24 +00:00
2021-06-11 17:51:46 +00:00
proc process_slots * (
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 : RuntimeConfig , state : var ForkedHashedBeaconState , slot : Slot ,
2022-01-17 11:19:58 +00:00
cache : var StateCache , info : var ForkedEpochInfo , flags : UpdateFlags ) :
Result [ void , cstring ] =
2021-06-11 17:51:46 +00:00
if not ( getStateField ( state , slot ) < slot ) :
if slotProcessed notin flags or getStateField ( state , slot ) ! = slot :
2022-01-17 11:19:58 +00:00
return err ( " process_slots: cannot rewind state to past slot " )
2021-06-04 10:38:00 +00:00
# Update the state so its slot matches that of the block
while getStateField ( state , slot ) < slot :
2021-09-28 18:08:03 +00:00
withState ( state ) :
2022-08-26 14:14:18 +00:00
withEpochInfo ( forkyState . data , info ) :
? advance_slot (
cfg , forkyState . data , forkyState . root , flags , cache , info )
2021-06-04 10:38:00 +00:00
2021-06-11 17:51:46 +00:00
if skipLastStateRootCalculation notin flags or
2022-08-26 14:14:18 +00:00
forkyState . data . slot < slot :
2021-06-11 17:51:46 +00:00
# Don't update state root for the slot of the block if going to process
# block after
2022-08-26 14:14:18 +00:00
forkyState . root = hash_tree_root ( forkyState . data )
2021-06-04 10:38:00 +00:00
2024-04-28 14:13:17 +00:00
maybeUpgradeState ( cfg , state , cache )
2021-06-04 10:38:00 +00:00
2022-01-17 11:19:58 +00:00
ok ( )
2021-06-04 10:38:00 +00:00
2021-06-11 17:51:46 +00:00
proc state_transition_block_aux (
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 : RuntimeConfig ,
2021-11-05 07:34:34 +00:00
state : var ForkyHashedBeaconState ,
2022-01-17 11:19:58 +00:00
signedBlock : SomeForkySignedBeaconBlock ,
2024-03-04 17:00:46 +00:00
cache : var StateCache , flags : UpdateFlags ) : Result [ BlockRewards , cstring ] =
2020-04-30 06:44:19 +00:00
# Block updates - these happen when there's a new block being suggested
# by the block proposer. Every actor in the network will update its state
# according to the contents of this block - but first they will validate
# that the block is sane.
2022-04-14 15:39:37 +00:00
if skipBlsValidation notin flags :
2022-01-17 11:19:58 +00:00
? verify_block_signature ( state . data , signedBlock )
2021-05-05 06:54:21 +00:00
trace " state_transition: processing block, signature passed " ,
signature = shortLog ( signedBlock . signature ) ,
blockRoot = shortLog ( signedBlock . root )
2024-03-04 17:00:46 +00:00
let blockRewards =
? process_block ( cfg , state . data , signedBlock . message , flags , cache )
2021-05-05 06:54:21 +00:00
2022-01-17 11:19:58 +00:00
if skipStateRootValidation notin flags :
? verifyStateRoot ( state . data , signedBlock . message )
2021-05-05 06:54:21 +00:00
# only blocks currently being produced have an empty state root - we use a
# separate function for those
2022-02-14 05:26:19 +00:00
doAssert not signedBlock . message . state_root . isZero ,
2021-05-05 06:54:21 +00:00
" see makeBeaconBlock for block production "
state . root = signedBlock . message . state_root
2024-03-04 17:00:46 +00:00
ok ( blockRewards )
2020-05-22 14:21:22 +00:00
2021-06-11 17:51:46 +00:00
func noRollback * ( state : var ForkedHashedBeaconState ) =
trace " Skipping rollback of broken state "
2021-06-04 10:38:00 +00:00
proc state_transition_block * (
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 : RuntimeConfig ,
2021-06-04 10:38:00 +00:00
state : var ForkedHashedBeaconState ,
2022-01-17 11:19:58 +00:00
signedBlock : SomeForkySignedBeaconBlock ,
2021-06-04 10:38:00 +00:00
cache : var StateCache , flags : UpdateFlags ,
2024-03-04 17:00:46 +00:00
rollback : RollbackForkedHashedProc ) : Result [ BlockRewards , cstring ] =
2021-06-04 10:38:00 +00:00
## `rollback` is called if the transition fails and the given state has been
## partially changed. If a temporary state was given to `state_transition`,
## it is safe to use `noRollback` and leave it broken, else the state
## object should be rolled back to a consistent state. If the transition fails
## before the state has been updated, `rollback` will not be called.
2021-06-11 17:51:46 +00:00
doAssert not rollback . isNil , " use noRollback if it ' s ok to mess up state "
2021-06-04 10:38:00 +00:00
2022-01-17 11:19:58 +00:00
let res = withState ( state ) :
2024-04-06 13:11:47 +00:00
when consensusFork = = type ( signedBlock ) . kind :
2022-08-26 14:14:18 +00:00
state_transition_block_aux ( cfg , forkyState , signedBlock , cache , flags )
2022-02-28 12:58:34 +00:00
else :
err ( " State/block fork mismatch " )
2021-06-11 17:51:46 +00:00
2022-01-17 11:19:58 +00:00
if res . isErr ( ) :
2021-06-11 17:51:46 +00:00
rollback ( state )
2022-01-17 11:19:58 +00:00
res
2021-06-04 10:38:00 +00:00
2021-06-03 09:42:25 +00:00
proc state_transition * (
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 : RuntimeConfig ,
2021-06-04 10:38:00 +00:00
state : var ForkedHashedBeaconState ,
2022-01-11 10:01:54 +00:00
signedBlock : SomeForkySignedBeaconBlock ,
2021-10-13 14:24:36 +00:00
cache : var StateCache , info : var ForkedEpochInfo , flags : UpdateFlags ,
2024-03-04 17:00:46 +00:00
rollback : RollbackForkedHashedProc ) : Result [ BlockRewards , cstring ] =
2021-06-04 10:38:00 +00:00
## Apply a block to the state, advancing the slot counter as necessary. The
## given state must be of a lower slot, or, in case the `slotProcessed` flag
## is set, can be the slot state of the same slot as the block (where the
## slot state is the state without any block applied). To create a slot state,
2024-04-19 11:31:15 +00:00
## advance the state corresponding to the parent block using
2021-06-04 10:38:00 +00:00
## `process_slots`.
##
## To run the state transition function in preparation for block production,
## use `makeBeaconBlock` instead.
##
## `rollback` is called if the transition fails and the given state has been
## partially changed. If a temporary state was given to `state_transition`,
## it is safe to use `noRollback` and leave it broken, else the state
## object should be rolled back to a consistent state. If the transition fails
## before the state has been updated, `rollback` will not be called.
2022-01-17 11:19:58 +00:00
? process_slots (
2021-10-13 14:24:36 +00:00
cfg , state , signedBlock . message . slot , cache , info ,
2022-01-17 11:19:58 +00:00
flags + { skipLastStateRootCalculation } )
2021-06-04 10:38:00 +00:00
state_transition_block (
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 , state , signedBlock , cache , flags , rollback )
2021-06-03 09:42:25 +00:00
2023-10-05 12:01:40 +00:00
func partialBeaconBlock * (
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 : RuntimeConfig ,
2024-04-18 07:30:01 +00:00
state : var ( phase0 . HashedBeaconState | altair . HashedBeaconState |
bellatrix . HashedBeaconState | capella . HashedBeaconState |
deneb . HashedBeaconState ) ,
2020-05-22 14:21:22 +00:00
proposer_index : ValidatorIndex ,
randao_reveal : ValidatorSig ,
eth1_data : Eth1Data ,
2020-06-29 17:30:19 +00:00
graffiti : GraffitiBytes ,
2024-04-17 20:44:29 +00:00
attestations : seq [ phase0 . Attestation ] ,
2020-05-22 14:21:22 +00:00
deposits : seq [ Deposit ] ,
2023-01-19 22:00:40 +00:00
validator_changes : BeaconBlockValidatorChanges ,
2021-09-29 12:10:44 +00:00
sync_aggregate : SyncAggregate ,
2023-09-05 13:59:17 +00:00
execution_payload : ForkyExecutionPayloadForSigning
) : auto =
const consensusFork = typeof ( state ) . kind
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/validator.md#preparing-for-a-beaconblock
2023-10-05 12:01:40 +00:00
var res = consensusFork . BeaconBlock (
2020-05-22 14:21:22 +00:00
slot : state . data . slot ,
proposer_index : proposer_index . uint64 ,
2022-03-16 07:20:40 +00:00
parent_root : state . latest_block_root ,
2023-10-05 12:01:40 +00:00
body : consensusFork . BeaconBlockBody (
2020-05-22 14:21:22 +00:00
randao_reveal : randao_reveal ,
2023-10-10 00:02:07 +00:00
eth1_data : eth1_data ,
2020-05-22 14:21:22 +00:00
graffiti : graffiti ,
2023-01-19 22:00:40 +00:00
proposer_slashings : validator_changes . proposer_slashings ,
attester_slashings : validator_changes . attester_slashings ,
2024-04-17 20:44:29 +00:00
attestations :
List [ phase0 . Attestation , Limit MAX_ATTESTATIONS ] ( attestations ) ,
2020-10-07 16:57:21 +00:00
deposits : List [ Deposit , Limit MAX_DEPOSITS ] ( deposits ) ,
2023-01-19 22:00:40 +00:00
voluntary_exits : validator_changes . voluntary_exits ) )
2020-05-22 14:21:22 +00:00
2023-09-05 13:59:17 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/altair/validator.md#preparing-a-beaconblock
when consensusFork > = ConsensusFork . Altair :
res . body . sync_aggregate = sync_aggregate
2021-06-21 08:35:24 +00:00
2024-04-18 01:00:04 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/bellatrix/validator.md#block-proposal
2023-09-05 13:59:17 +00:00
when consensusFork > = ConsensusFork . Bellatrix :
res . body . execution_payload = execution_payload . executionPayload
2021-09-30 01:07:24 +00:00
2024-03-14 06:26:36 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/capella/validator.md#block-proposal
2023-09-05 13:59:17 +00:00
when consensusFork > = ConsensusFork . Capella :
res . body . bls_to_execution_changes =
validator_changes . bls_to_execution_changes
2022-12-09 21:39:11 +00:00
2023-09-05 13:59:17 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/validator.md#constructing-the-beaconblockbody
when consensusFork > = ConsensusFork . Deneb :
2023-11-04 13:49:58 +00:00
res . body . blob_kzg_commitments = execution_payload . blobsBundle . commitments
2023-09-05 13:59:17 +00:00
2024-04-18 07:30:01 +00:00
res
func partialBeaconBlock * (
cfg : RuntimeConfig ,
state : var electra . HashedBeaconState ,
proposer_index : ValidatorIndex ,
randao_reveal : ValidatorSig ,
eth1_data : Eth1Data ,
graffiti : GraffitiBytes ,
2024-04-22 09:00:38 +00:00
attestations : seq [ electra . Attestation ] ,
2024-04-18 07:30:01 +00:00
deposits : seq [ Deposit ] ,
validator_changes : BeaconBlockValidatorChanges ,
sync_aggregate : SyncAggregate ,
execution_payload : ForkyExecutionPayloadForSigning
) : auto =
const consensusFork = typeof ( state ) . kind
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/validator.md#preparing-for-a-beaconblock
var res = consensusFork . BeaconBlock (
slot : state . data . slot ,
proposer_index : proposer_index . uint64 ,
parent_root : state . latest_block_root ,
body : consensusFork . BeaconBlockBody (
randao_reveal : randao_reveal ,
eth1_data : eth1_data ,
graffiti : graffiti ,
proposer_slashings : validator_changes . proposer_slashings ,
#attester_slashings: validator_changes.attester_slashings,
attestations :
2024-04-22 09:00:38 +00:00
List [ electra . Attestation , Limit MAX_ATTESTATIONS_ELECTRA ] ( attestations ) ,
2024-04-18 07:30:01 +00:00
deposits : List [ Deposit , Limit MAX_DEPOSITS ] ( deposits ) ,
voluntary_exits : validator_changes . voluntary_exits ) )
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/altair/validator.md#preparing-a-beaconblock
when consensusFork > = ConsensusFork . Altair :
res . body . sync_aggregate = sync_aggregate
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/bellatrix/validator.md#block-proposal
when consensusFork > = ConsensusFork . Bellatrix :
res . body . execution_payload = execution_payload . executionPayload
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/capella/validator.md#block-proposal
when consensusFork > = ConsensusFork . Capella :
res . body . bls_to_execution_changes =
validator_changes . bls_to_execution_changes
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/validator.md#constructing-the-beaconblockbody
when consensusFork > = ConsensusFork . Deneb :
res . body . blob_kzg_commitments = execution_payload . blobsBundle . commitments
debugRaiseAssert " either consolidate this within separate function or recombine, re when consensusFork >= foo and atts/attslashings; here to allow noninterference with pre-pectra "
2024-04-06 13:11:47 +00:00
2023-09-05 13:59:17 +00:00
res
2022-11-11 10:17:27 +00:00
2024-03-11 14:18:50 +00:00
proc makeBeaconBlockWithRewards * (
2021-09-29 12:10:44 +00:00
cfg : RuntimeConfig ,
state : var ForkedHashedBeaconState ,
proposer_index : ValidatorIndex ,
randao_reveal : ValidatorSig ,
eth1_data : Eth1Data ,
graffiti : GraffitiBytes ,
2024-04-22 09:00:38 +00:00
attestations : seq [ phase0 . Attestation ] | seq [ electra . Attestation ] ,
2021-09-29 12:10:44 +00:00
deposits : seq [ Deposit ] ,
2023-01-19 22:00:40 +00:00
validator_changes : BeaconBlockValidatorChanges ,
2021-09-29 12:10:44 +00:00
sync_aggregate : SyncAggregate ,
2023-03-05 01:40:21 +00:00
executionPayload : ForkyExecutionPayloadForSigning ,
2021-09-29 12:10:44 +00:00
rollback : RollbackForkedHashedProc ,
2022-05-17 19:56:15 +00:00
cache : var StateCache ,
# TODO:
# `verificationFlags` is needed only in tests and can be
# removed if we don't use invalid signatures there
2022-12-02 07:39:01 +00:00
verificationFlags : UpdateFlags ,
transactions_root : Opt [ Eth2Digest ] ,
2023-11-02 03:56:04 +00:00
execution_payload_root : Opt [ Eth2Digest ] ,
kzg_commitments : Opt [ KzgCommitments ] ) :
2024-03-11 14:18:50 +00:00
Result [ tuple [ blck : ForkedBeaconBlock , rewards : BlockRewards ] , cstring ] =
2021-11-18 12:02:43 +00:00
## Create a block for the given state. The latest block applied to it will
## be used for the parent_root value, and the slot will be take from
## state.slot meaning process_slots must be called up to the slot for which
## the block is to be created.
2021-09-29 12:10:44 +00:00
2024-03-11 14:18:50 +00:00
template makeBeaconBlock (
kind : untyped
) : Result [ tuple [ blck : ForkedBeaconBlock , rewards : BlockRewards ] , cstring ] =
2021-09-29 12:10:44 +00:00
# To create a block, we'll first apply a partial block to the state, skipping
# some validations.
2021-10-13 14:24:36 +00:00
var blck =
2021-09-29 12:10:44 +00:00
ForkedBeaconBlock . init (
2022-11-11 10:17:27 +00:00
partialBeaconBlock (
cfg , state . ` kind Data ` , proposer_index , randao_reveal , eth1_data ,
2023-01-19 22:00:40 +00:00
graffiti , attestations , deposits , validator_changes , sync_aggregate ,
2023-03-05 01:40:21 +00:00
executionPayload ) )
2021-09-29 12:10:44 +00:00
2022-09-28 01:15:10 +00:00
let res = process_block (
cfg , state . ` kind Data ` . data , blck . ` kind Data ` . asSigVerified ( ) ,
verificationFlags , cache )
2021-09-29 12:10:44 +00:00
if res . isErr :
rollback ( state )
2022-01-17 11:19:58 +00:00
return err ( res . error ( ) )
2021-09-29 12:10:44 +00:00
2023-11-02 03:56:04 +00:00
# Override for Builder API
2022-08-01 06:41:47 +00:00
if transactions_root . isSome and execution_payload_root . isSome :
withState ( state ) :
2024-02-29 12:37:08 +00:00
when consensusFork < ConsensusFork . Deneb :
# Nimbus doesn't support pre-Deneb builder API
2023-02-14 10:49:48 +00:00
discard
2023-06-26 16:05:02 +00:00
elif consensusFork = = ConsensusFork . Deneb :
2023-11-02 03:56:04 +00:00
forkyState . data . latest_execution_payload_header . transactions_root =
transactions_root . get
2023-06-26 16:05:02 +00:00
when executionPayload is deneb . ExecutionPayloadForSigning :
2024-03-14 06:26:36 +00:00
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody
2023-06-26 16:05:02 +00:00
forkyState . data . latest_block_header . body_root = hash_tree_root (
[ hash_tree_root ( randao_reveal ) ,
hash_tree_root ( eth1_data ) ,
hash_tree_root ( graffiti ) ,
hash_tree_root ( validator_changes . proposer_slashings ) ,
hash_tree_root ( validator_changes . attester_slashings ) ,
2024-04-17 20:44:29 +00:00
hash_tree_root (
List [ phase0 . Attestation , Limit MAX_ATTESTATIONS ] (
attestations ) ) ,
2023-06-26 16:05:02 +00:00
hash_tree_root ( List [ Deposit , Limit MAX_DEPOSITS ] ( deposits ) ) ,
hash_tree_root ( validator_changes . voluntary_exits ) ,
hash_tree_root ( sync_aggregate ) ,
execution_payload_root . get ,
hash_tree_root ( validator_changes . bls_to_execution_changes ) ,
2023-11-02 03:56:04 +00:00
hash_tree_root ( kzg_commitments . get )
2023-06-26 16:05:02 +00:00
] )
else :
raiseAssert " Attempt to use non-Deneb payload with post-Deneb state "
2024-04-03 14:43:43 +00:00
elif consensusFork = = ConsensusFork . Electra :
2024-04-22 09:00:38 +00:00
forkyState . data . latest_execution_payload_header . transactions_root =
transactions_root . get
debugRaiseAssert " makeBeaconBlock doesn ' t support Electra (i.e. check for missing beaconblock body fields) "
when executionPayload is electra . ExecutionPayloadForSigning :
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#beaconblockbody
forkyState . data . latest_block_header . body_root = hash_tree_root (
[ hash_tree_root ( randao_reveal ) ,
hash_tree_root ( eth1_data ) ,
hash_tree_root ( graffiti ) ,
hash_tree_root ( validator_changes . proposer_slashings ) ,
hash_tree_root ( validator_changes . attester_slashings ) ,
hash_tree_root (
List [ electra . Attestation , Limit MAX_ATTESTATIONS ] (
attestations ) ) ,
hash_tree_root ( List [ Deposit , Limit MAX_DEPOSITS ] ( deposits ) ) ,
hash_tree_root ( validator_changes . voluntary_exits ) ,
hash_tree_root ( sync_aggregate ) ,
execution_payload_root . get ,
hash_tree_root ( validator_changes . bls_to_execution_changes ) ,
hash_tree_root ( kzg_commitments . get )
] )
else :
raiseAssert " Attempt to use non-Electra payload with post-Deneb state "
2023-06-26 16:05:02 +00:00
else :
static : raiseAssert " Unreachable "
2021-10-18 16:37:27 +00:00
state . ` kind Data ` . root = hash_tree_root ( state . ` kind Data ` . data )
blck . ` kind Data ` . state_root = state . ` kind Data ` . root
2022-01-17 11:19:58 +00:00
2024-03-11 14:18:50 +00:00
ok ( ( blck : blck , rewards : res . get ) )
2021-09-29 12:10:44 +00:00
2023-09-27 15:10:28 +00:00
const payloadFork = typeof ( executionPayload ) . kind
2023-03-05 01:40:21 +00:00
when payloadFork = = ConsensusFork . Bellatrix :
2022-12-02 07:39:01 +00:00
case state . kind
2023-01-28 19:53:41 +00:00
of ConsensusFork . Phase0 : makeBeaconBlock ( phase0 )
of ConsensusFork . Altair : makeBeaconBlock ( altair )
of ConsensusFork . Bellatrix : makeBeaconBlock ( bellatrix )
2023-08-23 16:35:48 +00:00
else : raiseAssert " Attempt to use Bellatrix payload with post-Bellatrix state "
2023-03-05 01:40:21 +00:00
elif payloadFork = = ConsensusFork . Capella :
2022-12-02 07:39:01 +00:00
case state . kind
2023-01-28 19:53:41 +00:00
of ConsensusFork . Capella : makeBeaconBlock ( capella )
2023-08-23 16:35:48 +00:00
else : raiseAssert " Attempt to use Capella payload with non-Capella state "
2023-03-05 01:40:21 +00:00
elif payloadFork = = ConsensusFork . Deneb :
2022-12-08 16:21:53 +00:00
case state . kind
2023-08-23 16:35:48 +00:00
of ConsensusFork . Deneb : makeBeaconBlock ( deneb )
else : raiseAssert " Attempt to use Deneb payload with non-Deneb state "
2024-04-03 14:43:43 +00:00
elif payloadFork = = ConsensusFork . Electra :
2024-04-06 13:11:47 +00:00
case state . kind
2024-04-22 09:00:38 +00:00
of ConsensusFork . Electra : makeBeaconBlock ( electra )
2024-04-06 13:11:47 +00:00
else : raiseAssert " Attempt to use Electra payload with non-Electra state "
2023-03-05 01:40:21 +00:00
else :
2023-08-23 16:35:48 +00:00
{. error : " Unsupported fork " . }
2022-12-02 07:39:01 +00:00
2024-03-11 14:18:50 +00:00
proc makeBeaconBlock * (
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ,
proposer_index : ValidatorIndex , randao_reveal : ValidatorSig ,
eth1_data : Eth1Data , graffiti : GraffitiBytes ,
2024-04-22 09:00:38 +00:00
attestations : seq [ phase0 . Attestation ] | seq [ electra . Attestation ] ,
deposits : seq [ Deposit ] ,
2024-03-11 14:18:50 +00:00
validator_changes : BeaconBlockValidatorChanges ,
sync_aggregate : SyncAggregate ,
executionPayload : ForkyExecutionPayloadForSigning ,
rollback : RollbackForkedHashedProc , cache : var StateCache ,
verificationFlags : UpdateFlags ,
transactions_root : Opt [ Eth2Digest ] ,
execution_payload_root : Opt [ Eth2Digest ] ,
kzg_commitments : Opt [ KzgCommitments ] ) :
Result [ ForkedBeaconBlock , cstring ] =
let blockAndRewards =
? makeBeaconBlockWithRewards (
cfg , state , proposer_index , randao_reveal , eth1_data , graffiti ,
attestations , deposits , validator_changes , sync_aggregate ,
executionPayload , rollback , cache , verificationFlags , transactions_root ,
execution_payload_root , kzg_commitments )
ok ( blockAndRewards . blck )
2023-03-05 01:40:21 +00:00
proc makeBeaconBlock * (
2022-12-02 07:39:01 +00:00
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ,
proposer_index : ValidatorIndex , randao_reveal : ValidatorSig ,
eth1_data : Eth1Data , graffiti : GraffitiBytes ,
2024-04-22 09:00:38 +00:00
attestations : seq [ phase0 . Attestation ] | seq [ electra . Attestation ] ,
deposits : seq [ Deposit ] ,
2023-01-20 20:51:54 +00:00
validator_changes : BeaconBlockValidatorChanges ,
2023-03-05 01:40:21 +00:00
sync_aggregate : SyncAggregate ,
executionPayload : ForkyExecutionPayloadForSigning ,
2022-12-02 07:39:01 +00:00
rollback : RollbackForkedHashedProc , cache : var StateCache ) :
Result [ ForkedBeaconBlock , cstring ] =
makeBeaconBlock (
cfg , state , proposer_index , randao_reveal , eth1_data , graffiti ,
2023-01-20 20:51:54 +00:00
attestations , deposits , validator_changes , sync_aggregate ,
2023-03-05 01:40:21 +00:00
executionPayload , rollback , cache ,
2023-01-21 23:13:21 +00:00
verificationFlags = { } , transactions_root = Opt . none Eth2Digest ,
2023-11-02 03:56:04 +00:00
execution_payload_root = Opt . none Eth2Digest ,
kzg_commitments = Opt . none KzgCommitments )
2022-12-02 07:39:01 +00:00
2023-03-05 01:40:21 +00:00
proc makeBeaconBlock * (
2022-12-02 07:39:01 +00:00
cfg : RuntimeConfig , state : var ForkedHashedBeaconState ,
proposer_index : ValidatorIndex , randao_reveal : ValidatorSig ,
eth1_data : Eth1Data , graffiti : GraffitiBytes ,
2024-04-22 09:00:38 +00:00
attestations : seq [ phase0 . Attestation ] | seq [ electra . Attestation ] ,
deposits : seq [ Deposit ] ,
2023-01-20 20:51:54 +00:00
validator_changes : BeaconBlockValidatorChanges ,
2023-03-05 01:40:21 +00:00
sync_aggregate : SyncAggregate ,
executionPayload : ForkyExecutionPayloadForSigning ,
2022-12-02 07:39:01 +00:00
rollback : RollbackForkedHashedProc ,
cache : var StateCache , verificationFlags : UpdateFlags ) :
Result [ ForkedBeaconBlock , cstring ] =
makeBeaconBlock (
cfg , state , proposer_index , randao_reveal , eth1_data , graffiti ,
2023-01-20 20:51:54 +00:00
attestations , deposits , validator_changes , sync_aggregate ,
2023-03-05 01:40:21 +00:00
executionPayload , rollback , cache ,
2023-01-21 23:13:21 +00:00
verificationFlags = verificationFlags ,
2022-12-02 07:39:01 +00:00
transactions_root = Opt . none Eth2Digest ,
2023-11-02 03:56:04 +00:00
execution_payload_root = Opt . none Eth2Digest ,
kzg_commitments = Opt . none KzgCommitments )