Add tooltips for constants

This commit is contained in:
Ben Edgington
2022-03-26 12:47:35 +00:00
parent 038f7f67c2
commit 5ad57170eb
6 changed files with 214 additions and 17 deletions

57
bin/util/constants.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/bin/bash
config=$(mktemp)
phase0=$(mktemp)
altair=$(mktemp)
wget -O $config https://raw.githubusercontent.com/ethereum/consensus-specs/v1.1.1/configs/mainnet.yaml
wget -O $phase0 https://raw.githubusercontent.com/ethereum/consensus-specs/v1.1.1/presets/mainnet/phase0.yaml
wget -O $altair https://raw.githubusercontent.com/ethereum/consensus-specs/v1.1.1/presets/mainnet/altair.yaml
cat $config $phase0 $altair | awk '
BEGIN {
print "{"
}
# Skip comment lines
/^#/ { next }
/: / {
key = gensub(/^(.+): .+$/, "\\1", "1")
value = gensub(/^.+: (.+)$/, "\\1", "1")
print " \"" key "\": \"" value "\","
}
END {
# Lift constants from the spec manually
print " \"GENESIS_SLOT\": \"Slot(0)\","
print " \"GENESIS_EPOCH\": \"Epoch(0)\","
print " \"FAR_FUTURE_EPOCH\": \"Epoch(2**64 - 1)\","
print " \"BASE_REWARDS_PER_EPOCH\": \"uint64(4)\","
print " \"DEPOSIT_CONTRACT_TREE_DEPTH\": \"uint64(2**5) (= 32)\","
print " \"JUSTIFICATION_BITS_LENGTH\": \"uint64(4)\","
print " \"ENDIANNESS\": \"'little'\","
print " \"BLS_WITHDRAWAL_PREFIX\": \"Bytes1('0x00')\","
print " \"ETH1_ADDRESS_WITHDRAWAL_PREFIX\": \"Bytes1('0x01')\","
print " \"TIMELY_SOURCE_FLAG_INDEX\": \"0\","
print " \"TIMELY_TARGET_FLAG_INDEX\": \"1\","
print " \"TIMELY_HEAD_FLAG_INDEX\": \"2\","
print " \"TIMELY_SOURCE_WEIGHT\": \"uint64(14)\","
print " \"TIMELY_TARGET_WEIGHT\": \"uint64(26)\","
print " \"TIMELY_HEAD_WEIGHT\": \"uint64(14)\","
print " \"SYNC_REWARD_WEIGHT\": \"uint64(2)\","
print " \"PROPOSER_WEIGHT\": \"uint64(8)\","
print " \"WEIGHT_DENOMINATOR\": \"uint64(64)\","
print " \"DOMAIN_SYNC_COMMITTEE\": \"DomainType('0x07000000')\","
print " \"DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF\": \"DomainType('0x08000000')\","
print " \"DOMAIN_CONTRIBUTION_AND_PROOF\": \"DomainType('0x09000000')\","
print " \"DOMAIN_BEACON_PROPOSER\": \"DomainType('0x00000000')\","
print " \"DOMAIN_BEACON_ATTESTER\": \"DomainType('0x01000000')\","
print " \"DOMAIN_RANDAO\": \"DomainType('0x02000000')\","
print " \"DOMAIN_DEPOSIT\": \"DomainType('0x03000000')\","
print " \"DOMAIN_VOLUNTARY_EXIT\": \"DomainType('0x04000000')\","
print " \"DOMAIN_SELECTION_PROOF\": \"DomainType('0x05000000')\","
print " \"DOMAIN_AGGREGATE_AND_PROOF\": \"DomainType('0x06000000')\""
print "}"
}'

View File

@@ -23,7 +23,7 @@ module.exports = {
},
pathPrefix: `/altair`,
plugins: [
{
{
resolve: `gatsby-source-filesystem`,
options: {
name: `markdown-pages`,
@@ -38,6 +38,12 @@ module.exports = {
`gatsby-remark-autolink-headers`,
`gatsby-remark-numbered-footnotes`,
`gatsby-remark-katex`,
{
resolve: `my-tooltips`,
options: {
file: `${__dirname}/src/constants.json`
}
},
{
resolve: `gatsby-remark-external-links`,
options: {

View File

@@ -0,0 +1,28 @@
const visit = require("unist-util-visit")
const fs = require("fs")
module.exports = ({ markdownAST }, pluginOptions) => {
try {
const data = fs.readFileSync(pluginOptions.file, 'utf8')
const map = JSON.parse(data)
visit(markdownAST, "inlineCode", (node, index, parent) => {
// HTML in headings causes problems for the page index, so skip these
if (parent.type !== "heading") {
const text = node.value
const value = map[text]
if (value) {
const html = `<code title="${text} = ${value}">${text}</code>`
node.type = "html"
node.children = undefined
node.value = html
}
}
})
} catch (err) {
console.error(err)
}
return markdownAST
}

View File

@@ -0,0 +1,11 @@
{
"name": "my-tooltips",
"version": "1.0.0",
"description": "Add tooltips for constant values",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Ben Edgington",
"license": "ISC"
}

View File

@@ -514,8 +514,8 @@ The hysteresis levels are controlled by the [hysteresis parameters](/part3/confi
These are applied at the end of each epoch during [effective balance updates](/part3/transition/epoch#effective-balances-updates). Every validator in the state (whether active or not) has its effective balance updated as follows:
- If actual balance is less than effective balance minus 0.25 ( `= HYSTERESIS_DOWNWARD_MULTIPLIER / HYSTERESIS_QUOTIENT`) increments (ETH), then reduce the effective balance by an increment.
- If actual balance is more than effective balance plus 1.25 ( `= HYSTERESIS_UPWARD_MULTIPLIER / HYSTERESIS_QUOTIENT`) increments (ETH), then increase the effective balance by an increment.
- If actual balance is less than effective balance minus 0.25 ( `= ` `HYSTERESIS_DOWNWARD_MULTIPLIER` ` / ` `HYSTERESIS_QUOTIENT`) increments (ETH), then reduce the effective balance by an increment.
- If actual balance is more than effective balance plus 1.25 ( `= ` `HYSTERESIS_UPWARD_MULTIPLIER` ` / ` `HYSTERESIS_QUOTIENT`) increments (ETH), then increase the effective balance by an increment.
The effect of the hysteresis is that the effective balance cannot change more often than it takes for a validator's actual balance to change by 0.5 ETH, which would normally take several weeks or months.
@@ -1126,7 +1126,7 @@ How each validator's inactivity score is updated. The happy flow is right throug
Note that there is a floor of zero on the score.
When not in an inactivity leak validators' inactivity scores are reduced by `INACTIVITY_SCORE_RECOVERY_RATE + 1` per epoch when they make a timely target vote, and by `INACTIVITY_SCORE_RECOVERY_RATE - INACTIVITY_SCORE_BIAS` when they don't. So, even for non-performing validators, scores decrease outside a leak.
When not in an inactivity leak validators' inactivity scores are reduced by `INACTIVITY_SCORE_RECOVERY_RATE` ` + ` `1` per epoch when they make a timely target vote, and by `INACTIVITY_SCORE_RECOVERY_RATE` ` - ` `INACTIVITY_SCORE_BIAS` when they don't. So, even for non-performing validators, scores decrease outside a leak.
When in a leak, if $p$ is the participation rate between $0$ and $1$, and $\lambda$ is `INACTIVITY_SCORE_BIAS`, then the expected score after $N$ epochs is $\max (0, N((1-p)\lambda - p))$. For $\lambda = 4$ this is $\max (0, N(4 - 5p))$. So a validator that is participating 80% of the time or more can maintain a score that is bounded near zero. With less than 80% average participation, its score will increase unboundedly.
@@ -3892,7 +3892,7 @@ Since every validator attests one every epoch, there is an interplay between the
##### `MIN_SEED_LOOKAHEAD`
A random seed is used to select all the committees and proposers for an epoch. During each epoch, the beacon chain accumulates randomness from proposers via the RANDAO and stores it. The seed for the current epoch is based on the RANDAO output from the epoch `MIN_SEED_LOOKUP + 1` ago. With `MIN_SEED_LOOKAHEAD` set to one, the effect is that we can know the seed for the current epoch and the next epoch, but not beyond, since the next-but-one epoch depends on randomness from the current epoch that hasn't been accumulated yet.
A random seed is used to select all the committees and proposers for an epoch. During each epoch, the beacon chain accumulates randomness from proposers via the RANDAO and stores it. The seed for the current epoch is based on the RANDAO output from the epoch `MIN_SEED_LOOKAHEAD` ` + ` `1` ago. With `MIN_SEED_LOOKAHEAD` set to one, the effect is that we can know the seed for the current epoch and the next epoch, but not beyond, since the next-but-one epoch depends on randomness from the current epoch that hasn't been accumulated yet.
This mechanism is designed to allow sufficient time for committee members to find each other on the peer-to-peer network, and in future to sync up any shard data they need. But preventing committee makeup being known too far ahead limits the opportunity for coordinated collusion between validators.
@@ -3900,7 +3900,7 @@ This mechanism is designed to allow sufficient time for committee members to fin
The above notwithstanding, if an attacker has a large proportion of the stake, or is, for example, able to DoS block proposers for a while, then it might be possible for the the attacker to predict the output of the RANDAO further ahead than `MIN_SEED_LOOKAHEAD` would normally allow. In which case the attacker might be able to manipulate the make up of committees advantageously by performing judicious exits and activations of their validators.
To prevent this, we assume a maximum feasible lookahead that an attacker might achieve (`MAX_SEED_LOOKAHEAD`) and delay all activations and exits by this amount, which allows new randomness to come in via block proposals from honest validators. With `MAX_SEED_LOOKAHEAD` set to 4, if only 10% of validators are online and honest, then the chance that an attacker can succeed in forecasting the seed beyond (`MAX_SEED_LOOK_AHEAD - MIN_SEED_LOOKAHEAD`) = 3 epochs is $0.9^{3\times 32}$, which is about 1 in 25,000.
To prevent this, we assume a maximum feasible lookahead that an attacker might achieve (`MAX_SEED_LOOKAHEAD`) and delay all activations and exits by this amount, which allows new randomness to come in via block proposals from honest validators. With `MAX_SEED_LOOKAHEAD` set to 4, if only 10% of validators are online and honest, then the chance that an attacker can succeed in forecasting the seed beyond (`MAX_SEED_LOOK_AHEAD` ` - ` `MIN_SEED_LOOKAHEAD`) = 3 epochs is $0.9^{3\times 32}$, which is about 1 in 25,000.
##### `MIN_EPOCHS_TO_INACTIVITY_PENALTY`
@@ -3910,7 +3910,7 @@ The inactivity penalty is discussed [below](#inactivity_penalty_quotient_altair)
In order to safely onboard new validators, the beacon chain needs to take a view on what the Eth1 chain looks like. This is done by collecting votes from beacon block proposers - they are expected to consult an available Eth1 client in order to construct their vote.
`EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH` is the total number of votes for Eth1 blocks that are collected. As soon as half of this number of votes are for the same Eth1 block, that block is adopted by the beacon chain and deposit processing can continue.
`EPOCHS_PER_ETH1_VOTING_PERIOD` ` * ` `SLOTS_PER_EPOCH` is the total number of votes for Eth1 blocks that are collected. As soon as half of this number of votes are for the same Eth1 block, that block is adopted by the beacon chain and deposit processing can continue.
Rules for how validators select the right block to vote for are set out in the [validator guide](https://github.com/ethereum/consensus-specs/blob/v1.1.1/specs/phase0/validator.md#get_eth1_data). [`ETH1_FOLLOW_DISTANCE`](/part3/config/configuration#eth1_follow_distance) is the (approximate) minimum depth of block that can be considered.
@@ -3941,7 +3941,7 @@ This is the number of epochs of previous RANDAO mixes that are stored (one per e
In the epoch in which a misbehaving validator is slashed, its effective balance is added to an accumulator in the state. In this way, the `state.slashings` list tracks the total effective balance of all validators slashed during the last `EPOCHS_PER_SLASHINGS_VECTOR` epochs.
At a time `EPOCHS_PER_SLASHINGS_VECTOR // 2` after being slashed, a further penalty is applied to the slashed validator, based on the total amount of value slashed during the 4096 epochs before and the 4096 epochs after it was originally slashed.
At a time `EPOCHS_PER_SLASHINGS_VECTOR` ` // 2` after being slashed, a further penalty is applied to the slashed validator, based on the total amount of value slashed during the 4096 epochs before and the 4096 epochs after it was originally slashed.
The idea of this is to disproportionately punish coordinated attacks, in which many validators break the slashing conditions around the same time, while only lightly penalising validators that get slashed by making a mistake. Early designs for Eth2 would always slash a validator's entire deposit.
@@ -4007,7 +4007,7 @@ The whistleblower reward comes from new issuance of Ether on the beacon chain, b
This value supersedes `INACTIVITY_PENALTY_QUOTIENT`.
If the beacon chain hasn't finalised a checkpoint for longer than [`MIN_EPOCHS_TO_INACTIVITY_PENALTY`](#min_epochs_to_inactivity_penalty) epochs, then it enters "leak" mode. In this mode, any validator that does not vote (or votes for an incorrect target) is penalised an amount each epoch of `(effective_balance * inactivity_score) // (INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT_ALTAIR)`.
If the beacon chain hasn't finalised a checkpoint for longer than [`MIN_EPOCHS_TO_INACTIVITY_PENALTY`](#min_epochs_to_inactivity_penalty) epochs, then it enters "leak" mode. In this mode, any validator that does not vote (or votes for an incorrect target) is penalised an amount each epoch of `(effective_balance * inactivity_score) // (` `INACTIVITY_SCORE_BIAS` ` * ` `INACTIVITY_PENALTY_QUOTIENT_ALTAIR` `)`.
In Altair, `inactivity_score` is a per-validator quantity, whereas previously validators were penalised by a globally calculated amount when they missed a duty during a leak. See [inactivity penalties](/part3/config/configuration#inactivity-penalties) for more on the rationale for this and how this score is calculated per validator.
@@ -4017,7 +4017,7 @@ To examine the effect of the leak on a single validator's balance, assume that d
The effective balance $B$ will remain constant for a while, by design, during which time the total amount of the penalty after $n$ epochs would be $n(n+1)B / 2\alpha$: the famous "quadratic leak". If $B$ were continuously variable, the penalty would satisfy $\frac{dB}{dt}=-\frac{Bt}{\alpha}$, which can be solved to give $B(t)=B_0e^{-t^2/2\alpha}$. The actual behaviour is somewhere between these two since the effective balance decreases in a step-wise fashion.
In the continuous case, the `INACTIVITY_PENALTY_QUOTIENT`, $\alpha$, is the square of the time it takes to reduce the balance of a non-participating validator to $1 / \sqrt{e}$, or around 60.7% of its initial value. With the value of `INACTIVITY_PENALTY_QUOTIENT` at `3 * 2**24`, this equates to around seven thousand epochs, or 31.5 days.
In the continuous case, the `INACTIVITY_PENALTY_QUOTIENT`, $\alpha$, is the square of the time it takes to reduce the balance of a non-participating validator to $1 / \sqrt{e}$, or around 60.7% of its initial value. With the value of `INACTIVITY_PENALTY_QUOTIENT_ALTAIR` at `3 * 2**24`, this equates to around seven thousand epochs, or 31.5 days.
The idea for the inactivity leak (aka the quadratic leak) was proposed in the original [Casper FFG paper](https://arxiv.org/abs/1710.09437). The problem it addresses is that, if a large fraction of the validator set were to go offline at the same time, it would not be possible to continue finalising checkpoints, since a majority vote from validators representing 2/3 of the total stake is required for finalisation.
@@ -4031,7 +4031,7 @@ The value was decreased by one quarter in the Altair upgrade from `2**26` to `3
##### `MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR`
When a validator is first convicted of a slashable offence, an initial penalty is applied. This is calculated as, `validator.effective_balance // MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR`.
When a validator is first convicted of a slashable offence, an initial penalty is applied. This is calculated as, `validator.effective_balance // ` `MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR`.
Thus, the initial slashing penalty is between 0.25 Ether and 0.5 Ether depending on the validator's effective balance (which is between 16 and 32 Ether; note that effective balance is denominated in Gwei).
@@ -4261,7 +4261,7 @@ When in a leak, if $p$ is the participation rate between $0$ and $1$, and $\lamb
##### `INACTIVITY_SCORE_RECOVERY_RATE`
When not in an inactivity leak, validators' inactivity scores are reduced by `INACTIVITY_SCORE_RECOVERY_RATE + 1` per epoch when they make a timely target vote, and by `INACTIVITY_SCORE_RECOVERY_RATE - INACTIVITY_SCORE_BIAS` when they don't. So, even for non-performing validators, scores decrease three times faster than they increase.
When not in an inactivity leak, validators' inactivity scores are reduced by `INACTIVITY_SCORE_RECOVERY_RATE` ` + 1` per epoch when they make a timely target vote, and by `INACTIVITY_SCORE_RECOVERY_RATE` ` - ` `INACTIVITY_SCORE_BIAS` when they don't. So, even for non-performing validators, scores decrease three times faster than they increase.
The new scoring system means that some validators will continue to be penalised due to the leak, even after finalisation starts again. This is [intentional](https://github.com/ethereum/consensus-specs/issues/2098). When the leak causes the beacon chain to finalise, at that point we have just 2/3 of the stake online. If we immediately stop the leak (as we used to), then the amount of stake online would remain close to 2/3 and the chain would be vulnerable to flipping in and out of finality as small numbers of validators come and go. We saw this behaviour on some of the testnets prior to launch. Continuing the leak after finalisation serves to increase the balances of participating validators to greater than 2/3, providing a margin that should help to prevent such behaviour.
@@ -6756,7 +6756,7 @@ Without wanting to go full [Yellow Paper](https://ethereum.github.io/yellowpaper
We will define a base reward $B$ that we will see turns out to be the expected long-run average income of an optimally performing validator per epoch (ignoring validator set size changes). The total number of active validators is $N$.
The base reward is calculated from a [base reward per increment](#def_get_base_reward_per_increment), $b$. An "increment" is a unit of effective balance in terms of [`EFFECTIVE_BALANCE_INCREMENT`](/part3/config/preset#effective_balance_increment). $B = 32b$ because [`MAX_EFFECTIVE_BALANCE`](/part3/config/preset#max_effective_balance) = `32 * EFFECTIVE_BALANCE_INCREMENT`
The base reward is calculated from a [base reward per increment](#def_get_base_reward_per_increment), $b$. An "increment" is a unit of effective balance in terms of [`EFFECTIVE_BALANCE_INCREMENT`](/part3/config/preset#effective_balance_increment). $B = 32b$ because [`MAX_EFFECTIVE_BALANCE`](/part3/config/preset#max_effective_balance) = `32 * ` `EFFECTIVE_BALANCE_INCREMENT`
Other quantities we will use in rewards calculation are the [incentivization weights](/part3/config/constants#incentivization-weights): $W_s$, $W_t$, $W_h$, and $W_y$ being the weights for correct source, target, head, and sync committee votes respectively; $W_p$ being the proposer weight; and the weight denominator $W_{\Sigma}$ which is the sum of the weights.
@@ -7025,7 +7025,7 @@ def process_slashings(state: BeaconState) -> None:
Slashing penalties are applied in two stages: the first stage is in [`slash_validator()`](/part3/helper/mutators#def_slash_validator), immediately on detection; the second stage is here.
In `slash_validator()` the withdrawable epoch is set [`EPOCHS_PER_SLASHINGS_VECTOR`](/part3/config/preset#epochs_per_slashings_vector) in the future, so in this function we are considering all slashed validators that are halfway to being withdrawable, that is, completely exited from the protocol. Equivalently, they were slashed `EPOCHS_PER_SLASHINGS_VECTOR // 2` epochs ago (about 18 days).
In `slash_validator()` the withdrawable epoch is set [`EPOCHS_PER_SLASHINGS_VECTOR`](/part3/config/preset#epochs_per_slashings_vector) in the future, so in this function we are considering all slashed validators that are halfway to being withdrawable, that is, completely exited from the protocol. Equivalently, they were slashed `EPOCHS_PER_SLASHINGS_VECTOR` ` // 2` epochs ago (about 18 days).
To calculate the additional slashing penalty, we do the following:
1. Find the sum of the effective balances (at the time of the slashing) of all validators that were slashed in the previous `EPOCHS_PER_SLASHINGS_VECTOR` epochs (36 days). These are stored as a vector in the state.
@@ -7699,7 +7699,7 @@ Before the Ethereum beacon chain genesis has been triggered, and for every Ether
- `eth1_timestamp` is the Unix timestamp corresponding to `eth1_block_hash`
- `deposits` is the sequence of all deposits, ordered chronologically, up to (and including) the block with hash `eth1_block_hash`
Proof-of-work blocks must only be considered once they are at least `SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE` seconds old (i.e. `eth1_timestamp + SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE <= current_unix_time`). Due to this constraint, if `GENESIS_DELAY < SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE`, then the `genesis_time` can happen before the time/state is first known. Values should be configured to avoid this case.
Proof-of-work blocks must only be considered once they are at least `SECONDS_PER_ETH1_BLOCK` ` * ` `ETH1_FOLLOW_DISTANCE` seconds old (i.e. `eth1_timestamp + ` `SECONDS_PER_ETH1_BLOCK` ` * ` `ETH1_FOLLOW_DISTANCE` ` <= current_unix_time`). Due to this constraint, if `GENESIS_DELAY` ` < ` `SECONDS_PER_ETH1_BLOCK` ` * ` `ETH1_FOLLOW_DISTANCE`, then the `genesis_time` can happen before the time/state is first known. Values should be configured to avoid this case.
### Initialisation
@@ -7807,9 +7807,9 @@ Note that for the pure Altair networks, we don't apply `upgrade_to_altair` since
#### Upgrading the state
If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == ALTAIR_FORK_EPOCH`, an irregular state change is made to upgrade to Altair.
If `state.slot % ` `SLOTS_PER_EPOCH` ` == 0` and `compute_epoch_at_slot(state.slot) == ` `ALTAIR_FORK_EPOCH`, an irregular state change is made to upgrade to Altair.
The upgrade occurs after the completion of the inner loop of `process_slots` that sets `state.slot` equal to `ALTAIR_FORK_EPOCH * SLOTS_PER_EPOCH`.
The upgrade occurs after the completion of the inner loop of `process_slots` that sets `state.slot` equal to `ALTAIR_FORK_EPOCH` ` * ` `SLOTS_PER_EPOCH`.
Care must be taken when transitioning through the fork boundary as implementations will need a modified [state transition function](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function) that deviates from the Phase 0 document.
In particular, the outer `state_transition` function defined in the Phase 0 document will not expose the precise fork slot to execute the upgrade in the presence of skipped slots at the fork boundary. Instead the logic must be within `process_slots`.

95
src/constants.json Normal file
View File

@@ -0,0 +1,95 @@
{
"PRESET_BASE": "'mainnet'",
"TERMINAL_TOTAL_DIFFICULTY": "115792089237316195423570985008687907853269984665640564039457584007913129638912",
"TERMINAL_BLOCK_HASH": "0x0000000000000000000000000000000000000000000000000000000000000000",
"MIN_GENESIS_ACTIVE_VALIDATOR_COUNT": "16384",
"MIN_GENESIS_TIME": "1606824000",
"GENESIS_FORK_VERSION": "0x00000000",
"GENESIS_DELAY": "604800",
"ALTAIR_FORK_VERSION": "0x01000000",
"ALTAIR_FORK_EPOCH": "74240 # Oct 27, 2021, 10:56:23am UTC",
"MERGE_FORK_VERSION": "0x02000000",
"MERGE_FORK_EPOCH": "18446744073709551615",
"SHARDING_FORK_VERSION": "0x03000000",
"SHARDING_FORK_EPOCH": "18446744073709551615",
"SECONDS_PER_SLOT": "12",
"SECONDS_PER_ETH1_BLOCK": "14",
"MIN_VALIDATOR_WITHDRAWABILITY_DELAY": "256",
"SHARD_COMMITTEE_PERIOD": "256",
"ETH1_FOLLOW_DISTANCE": "2048",
"INACTIVITY_SCORE_BIAS": "4",
"INACTIVITY_SCORE_RECOVERY_RATE": "16",
"EJECTION_BALANCE": "16000000000",
"MIN_PER_EPOCH_CHURN_LIMIT": "4",
"CHURN_LIMIT_QUOTIENT": "65536",
"DEPOSIT_CHAIN_ID": "1",
"DEPOSIT_NETWORK_ID": "1",
"DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cBB839Cbe05303d7705Fa",
"MAX_COMMITTEES_PER_SLOT": "64",
"TARGET_COMMITTEE_SIZE": "128",
"MAX_VALIDATORS_PER_COMMITTEE": "2048",
"SHUFFLE_ROUND_COUNT": "90",
"HYSTERESIS_QUOTIENT": "4",
"HYSTERESIS_DOWNWARD_MULTIPLIER": "1",
"HYSTERESIS_UPWARD_MULTIPLIER": "5",
"SAFE_SLOTS_TO_UPDATE_JUSTIFIED": "8",
"MIN_DEPOSIT_AMOUNT": "1000000000",
"MAX_EFFECTIVE_BALANCE": "32000000000",
"EFFECTIVE_BALANCE_INCREMENT": "1000000000",
"MIN_ATTESTATION_INCLUSION_DELAY": "1",
"SLOTS_PER_EPOCH": "32",
"MIN_SEED_LOOKAHEAD": "1",
"MAX_SEED_LOOKAHEAD": "4",
"EPOCHS_PER_ETH1_VOTING_PERIOD": "64",
"SLOTS_PER_HISTORICAL_ROOT": "8192",
"MIN_EPOCHS_TO_INACTIVITY_PENALTY": "4",
"EPOCHS_PER_HISTORICAL_VECTOR": "65536",
"EPOCHS_PER_SLASHINGS_VECTOR": "8192",
"HISTORICAL_ROOTS_LIMIT": "16777216",
"VALIDATOR_REGISTRY_LIMIT": "1099511627776",
"BASE_REWARD_FACTOR": "64",
"WHISTLEBLOWER_REWARD_QUOTIENT": "512",
"PROPOSER_REWARD_QUOTIENT": "8",
"INACTIVITY_PENALTY_QUOTIENT": "67108864",
"MIN_SLASHING_PENALTY_QUOTIENT": "128",
"PROPORTIONAL_SLASHING_MULTIPLIER": "1",
"MAX_PROPOSER_SLASHINGS": "16",
"MAX_ATTESTER_SLASHINGS": "2",
"MAX_ATTESTATIONS": "128",
"MAX_DEPOSITS": "16",
"MAX_VOLUNTARY_EXITS": "16",
"INACTIVITY_PENALTY_QUOTIENT_ALTAIR": "50331648",
"MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR": "64",
"PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR": "2",
"SYNC_COMMITTEE_SIZE": "512",
"EPOCHS_PER_SYNC_COMMITTEE_PERIOD": "256",
"MIN_SYNC_COMMITTEE_PARTICIPANTS": "1",
"GENESIS_SLOT": "Slot(0)",
"GENESIS_EPOCH": "Epoch(0)",
"FAR_FUTURE_EPOCH": "Epoch(2**64 - 1)",
"BASE_REWARDS_PER_EPOCH": "uint64(4)",
"DEPOSIT_CONTRACT_TREE_DEPTH": "uint64(2**5) (= 32)",
"JUSTIFICATION_BITS_LENGTH": "uint64(4)",
"ENDIANNESS": "little",
"BLS_WITHDRAWAL_PREFIX": "Bytes1(0x00)",
"ETH1_ADDRESS_WITHDRAWAL_PREFIX": "Bytes1(0x01)",
"TIMELY_SOURCE_FLAG_INDEX": "0",
"TIMELY_TARGET_FLAG_INDEX": "1",
"TIMELY_HEAD_FLAG_INDEX": "2",
"TIMELY_SOURCE_WEIGHT": "uint64(14)",
"TIMELY_TARGET_WEIGHT": "uint64(26)",
"TIMELY_HEAD_WEIGHT": "uint64(14)",
"SYNC_REWARD_WEIGHT": "uint64(2)",
"PROPOSER_WEIGHT": "uint64(8)",
"WEIGHT_DENOMINATOR": "uint64(64)",
"DOMAIN_SYNC_COMMITTEE": "DomainType(0x07000000)",
"DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF": "DomainType(0x08000000)",
"DOMAIN_CONTRIBUTION_AND_PROOF": "DomainType(0x09000000)",
"DOMAIN_BEACON_PROPOSER": "DomainType(0x00000000)",
"DOMAIN_BEACON_ATTESTER": "DomainType(0x01000000)",
"DOMAIN_RANDAO": "DomainType(0x02000000)",
"DOMAIN_DEPOSIT": "DomainType(0x03000000)",
"DOMAIN_VOLUNTARY_EXIT": "DomainType(0x04000000)",
"DOMAIN_SELECTION_PROOF": "DomainType(0x05000000)",
"DOMAIN_AGGREGATE_AND_PROOF": "DomainType(0x06000000)"
}