Deposits and Eth1 voting
get_deposit_root
function of the deposit contract returns the deposit root which uniquely identifies the set of deposits made so far.Eth1Data
object) contain deposit roots.SLOTS_PER_ETH1_VOTING_PERIOD
) and the voting threshold is 1/2 (see process_eth1_data
). When the threshold is met, the corresponding deposit root becomes the new source of truth against which Eth1 deposits are authenticated.get_eth1_vote
. The strategy is based on tallying upon the most popular valid deposit root.ETH1_FOLLOW_DISTANCE
constant specifies the minimum age (measured in Eth1 blocks from the subjective tip) that deposit roots should have for honest Eth1 voters to consider valid. It corresponds to about 4 hours which should be sufficiently large to ensure that a deposit root that passes the 1/2 threshold never gets reverted in the eth1 PoW chain. (If such a reversion happens emergency manual intervention may be required.)MAX_DEPOSITS
limit) to be processed in beacon blocks to mitigate DoS and grinding attacks that withhold deposits. See the first assert
in process_operations
.DEPOSIT_CONTRACT_ADDRESS
is currently marked as “TBD”. The intent is to well-publicise this address across EF blog, client blogs, and other sources to set the address in an effort to mitigate scam deposit addresses. The ENS name depositcontract.eth
may be programmed to immutably point to the deposit contract address for 128 years.MIN_DEPOSIT_AMOUNT
). Eth1 holders with less than 1 ETH have to pool funds or use alternative infrastructure such as exchanges to get an Eth2 validator balance.signature
field is a BLS proof of possession, i.e. a proof that the private key corresponding to the pubkey
is known by the signer. This is a mechanism to avoid so-called rogue key attackers with BLS aggregation. The proof of possession is not verified in the deposit contract on the eth1 chain, saving significant gas especially that Eth1 does not have BLS12-381 precompiles. Note that process_deposit only checks the proof of possession for the first deposit for a particular pubkey
.List[DepositData]
. (Notice the last line of get_deposit_root
is the List
length mixin.) This makes deposit roots friendly to SSZ partials.depth=DEPOSIT_CONTRACT_TREE_DEPTH + 1
in process_deposit
).Transfer
operation). Either Eth1 will be fully integrated into Eth2 or a two-way bridge will be built before validator liquidity is enabled.block_hash
field. This field identifies one of multiple Eth1 chains that could correspond to the same deposit root. It is also infrastructure that may be useful to finalise Eth1 using the Eth2 finality mechanism, and build a two-way bridge.Genesis
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
by MAX_EFFECTIVE_BALANCE
.) This minimum is a balance between being low enough to achieve in the early/untrusted system, yet large enough is a mitigation against an attacker monopolising the beacon chain early on. IMIN_GENESIS_TIME
constant specifies the earliest time for the Eth2 genesis. A placeholder of January 3, 2020 is currently specified. A specific date will be chosen following successful audits and testnets.is_valid_genesis_state
function formalises the genesis trigger. It is defined outside of the deposit contract to make use of the expressibility of get_active_validator_indices
, and for it to be redefined if necessary. For example, MIN_GENESIS_TIME
may be push back depending on the expected production-readiness of implementations.MIN_GENESIS_DELAY == 1 day
, the genesis block is constrained to happen at 00:00 UTC (see genesis_time=eth1_timestamp - eth1_timestamp % MIN_GENESIS_DELAY
in initialize_beacon_state_from_eth1
). Since MIN_GENESIS_DELAY * SLOTS_PER_EPOCH
divides MIN_GENESIS_DELAY
, an epoch transition will occur every day at 00:00 UTC.genesis_time
is designed to give validators at least one day of advance notice before the genesis block (see + 2 * MIN_GENESIS_DELAY
in initialize_beacon_state_from_eth1
). This allows the Eth1 block triggering Eth2 genesis to be safely confirmed, and allow validators to manually check or configure the genesis block if required. Note that MIN_GENESIS_DELAY
is configurable to smaller values for ease in kicking off testnetsGENESIS_EPOCH
are prevented on an adhoc basis with simple if
statements in get_previous_epoch
, process_justification_and_finalization
, and process_rewards_and_penalties
.Hashing and merkleisation
state.eth1_data
object is the partial Merkleisation of the same object with deposit_root
replaced by the deposit tree. Other examples of partial Merkleisations include header.parent_root
, header.block_root
, header.state_root
, crosslink.parent_root
, state.historical_roots[i]
.historical_roots
(along with block_roots
and state_roots
) in the beacon state allow for any historical consensus object in a beacon chain to be accessed with a bounded-size Merkle path. The historical roots infrastructure can be thought of a constant-size append-only accumulator with permanent witnesses.block
is defined as hash_tree_root(block)
(not the hash_tree_root(signed_beacon_block)
. In other words, the signature is excluded from the block identifier. (There is a one-to-one correspondence between hash_tree_root(block)
and hash_tree_root(signed_block)
because BLS signature are unique.)latest_block_header
) to compute the block root of its latest block. This allows for the state transition function check block.parent_root
is valid from the state only, i.e. without oracle access to the parent root.validators
and balances
. The high-churn balances
are segregated as a Merkleisation optimisation. Indeed, validators
change comparatively infrequently and fully re-Merkleising balances
at every epoch is significantly cheaper than re-Merkleising the full registry.state.validators
. This is a DoS-protection mechanism to avoid unnecessary hashing and to prevent minor changes to balance having much effect on fork choice stability. See balance < validator.effective_balance or validator.effective_balance + 3 * HALF_INCREMENT < balance
in process_final_updates
.Signatures
bls_aggregate_pubkeys
). (Notice signature aggregation is done offchain so the performance of G2 additions matters much less, but at the expense of larger messages on gossip channels.)withdrawal_credentials
a tree of secret hashes. In case of a quantum apocalypse, BLS signatures will be deactivated (e.g. by redefining bls_verify
to always return False
) and Lamport signatures can ensure a safe transition for validators.BLS_WITHDRAWAL_PREFIX
constant specifies the format of the validator withdrawal credentials. This allows, for example, for different signatures to be specified in the future.BeaconBlock
s (rather than SignedBeaconBlocks
) allows for the consecutive headers to be verified via communicating a single aggregated signature.Incentivisation
integer_squareroot
is equivalent to math.floor(math.sqrt(n))
, and was implemented using Newton’s method to avoid external dependencies.BASE_REWARD_FACTOR
constant (assuming SECONDS_PER_SLOT
and SLOTS_PER_EPOCH
fixed) dictates the issuance schedule. It was chosen to issue at most 2^21 ETH (~2 million ETH) per year in the worst-case. The worst-case corresponds to 2^27 ETH effective balance (i.e. all ETH in existence today and some), with all validators making perfect attestations (matching source, target, head, and crosslink) that are perfectly included on-chain. In practice, the issuance is expected incur significantly less than 1% dilution per year.effective_balance
which has a cap of MAX_EFFECTIVE_BALANCE
, so in practice rewards do no compound. A validator is expected to eventually withdraw rewards and split across multiple validators to reap the benefits of compounding.MIN_SLASHING_PENALTY_QUOTIENT
) of their effective balance. So if a validator has 32 ETH of effective balance they will lose at least 1 ETH.Types
uint8
(a byte) uint64
(unsigned 64-bit integer) and bool
.get_head
for tie breaking).Randomness and shuffling
+ int_to_bytes(epoch, length=32)
in get_seed
) to avoid the randomness beacon producing the same seed across epochs with all skip slots.xor
in process_randao
is (slightly) more secure than using hash
. To illustrate why, imagine an attacker can grind randomness in the current epoch such that two of his validators are the last proposers, in a different order, in two resulting samplings of the next epochs. The commutativity of xor
makes those two samplings equivalent, hence reducing the attacker’s grinding opportunity for the next epoch versus hash
(which is not commutative). The strict security improvement may simplify the derivation of RANDAO security formal lower bounds.MIN_SEED_LOOKAHEAD
).MAX_SEED_LOOKAHEAD
: In adversarial conditions (attacker with a large stake and/or poor liveness) it is possible for an attacker to predict the randomness from RANDAO some time in advance. This “lookahead” could be used by an attacker to manipulate committee shufflings by grinding activations and exits (e.g. using self-slashing). We protect against this by delaying activations and exits by this certain security parameter.MAX_SEED_LOOKAHEAD - MIN_SEED_LOOKAHEAD
: This security parameter (set to 3) ensures with high probability that an attacker cannot unfairly manipulate the shuffling (e.g. to craft invalid or unavailable crosslinks). Indeed, even if there’s only 10% of validators that are honest and online then the probability an attacker can know the randomness 3 epochs beyond MIN_SEED_LOOKAHEAD
is (1 - 10%)**(3*64), which is about 1 in a billion.SHUFFLE_ROUND_COUNT
(intermediate): Notice that SHUFFLE_ROUND_COUNT
is not a power of two because swap or not can be considered a black box.compute_shuffled_index
) as a cryptographic black box and trust the cryptographers. Having said that, intuitively, the shuffling is just the repeated iteration (SHUFFLE_ROUND_COUNT
times) of a simple reflection permutation around a pseudo-randomly selected pivot.randao_mixes
: Allow for far-reaching reconstructions of shufflings.Blocks
extraData
field in Eth1 blocks, beacon blocks have a free-form 32-bytes “graffiti”. Graffiti are meant to be a vector for permissionless innovation.body_root
is the Merkleisation of a BeaconBlockBody
.MAX_PROPOSER_SLASHINGS
, MAX_ATTESTER_SLASHINGS
, etc.). [TODO: Add maximum block size.] This is a DoS protection mechanism.latest_block_header
: The beacon state keeps track of information the latest processed block header. For circularity reasons, it does not keep track of the signature
, and only adds the state_root
in the next slot.latest_block_header
allows for a clean (BeaconState, BeaconBlock) -> BeaconState
transition function where the parent_root
is internally calculated and checked without “oracle access” (see assert block.parent_root == hash_tree_root(state.latest_block_header)
in process_block_header
).Validators
83) FAR_FUTURE_EPOCH: The constant acts as a flag to indicate that Validator
status epochs have not been written to.
84) Fair proposer selection: Notice that the while True
loop in compute_proposer_index
will terminate
Attestations
signature
is stripped off after being verified as they are no longer needed and we can save space/hashing in the BeaconState
. The inclusion_delay
and proposer_index
are added for incentivisation purposes—see “Proposer and inclusion delay micro-rewards” in get_attestation_deltas
.IndexedAttestation
is slightly more powerful than using just one.aggregation_bits
which consumes just one bit per committee member.process_proposer_slashing
).indices == sorted(set(indices))
—to allow for network-level compression like SPDY.MIN_ATTESTATION_INCLUSION_DELAY
:Light clients
compact_validators
: Reduce hashing overhead, and more efficient light clients. compact_balance
chosen to have 15 bits for future-proofness, e.g. if STARK-based signatures force us to increase the minimum deposit size.historical_roots
: A really neat append-only accumulator. Notice that witnesses are permanent.CHURN_LIMIT_QUOTIENT
: The churn in the active validator pool, i.e. the amount by which validators activate and exit, is limited so that light clients can safely resync after being disconnected, up to some weak subjectivity bound.Versioning
Fork
object which contains previous_version
and current_version
). The fork versioning ties into the signature scheme as a replay protection mechanism.SECONDS_PER_SLOT
plus or minus one second.SECONDS_PER_SLOT
constant defines the number as part of the fork choice rule (as opposed to the state transition function). As small as we can safely get it. A block is only accepted into the view of the fork choice if the current time is at least state.genesis_time + block.slot * SECONDS_PER_SLOT
.Checkpointing and finality
Design principles
Technicalities
max(1,
in get_committee_count_at_slot
and get_total_balance
.Draft
MAX_ATTESTATIONS
vs MAX_COMMITTEES_PER_SLOT // SLOTS_PER_EPOCH
: Notice that MAX_ATTESTATIONS
is 2 times larger than MAX_COMMITTEES_PER_SLOT // SLOTS_PER_EPOCH
(128 vs 16). This buffer allows for the beacon chain to absorb some amount of imperfectly-aggregated attestations for the same committee, as well as provide resilience against skip slots.SLOTS_PER_ETH1_VOTING_PERIOD == 1024
). Crosslink committees can be as small as TARGET_COMMITTEE_SIZE == 128
.MAX_...
: DoS mitigation by capping the maximum size of beacon blocks.