mirror of
https://github.com/ethereum/consensus-specs.git
synced 2026-01-10 04:38:03 -05:00
Use mdformat for markdown formatting (#4244)
* Replace skip footnote with html block * Remove unnecessary duration columns * Add mdformat to pyproject * Start to use mdformat-toc * Remove table of contents headers * Fix empty header * Finally, run mdformat * Remove doctoc from CI * Fix issue with eip7732 * Error if linter changes something in CI
This commit is contained in:
11
.github/workflows/run-tests.yml
vendored
11
.github/workflows/run-tests.yml
vendored
@@ -29,20 +29,15 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: ''
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
with:
|
||||
python-version: '3.12.4'
|
||||
cache: ''
|
||||
- name: Install doctoc
|
||||
run: npm install -g doctoc@2.2.0
|
||||
- name: Run linter for pyspec
|
||||
run: make lint
|
||||
run: |
|
||||
make lint
|
||||
git diff --exit-code
|
||||
|
||||
whitespace:
|
||||
runs-on: [self-hosted-ghr-custom, size-l-x64, profile-consensusSpecs]
|
||||
|
||||
20
Makefile
20
Makefile
@@ -58,6 +58,7 @@ VENV = venv
|
||||
PYTHON_VENV = $(VENV)/bin/python3
|
||||
PIP_VENV = $(VENV)/bin/pip3
|
||||
CODESPELL_VENV = $(VENV)/bin/codespell
|
||||
MDFORMAT_VENV = $(VENV)/bin/mdformat
|
||||
|
||||
# Make a virtual environment.
|
||||
$(VENV):
|
||||
@@ -185,24 +186,9 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/*/*.md) \
|
||||
$(wildcard $(SPEC_DIR)/_features/*/*/*.md) \
|
||||
$(wildcard $(SSZ_DIR)/*.md)
|
||||
|
||||
# Generate ToC sections & save copy of original if modified.
|
||||
%.toc:
|
||||
@cp $* $*.tmp; \
|
||||
doctoc $* > /dev/null; \
|
||||
if diff -q $* $*.tmp > /dev/null; then \
|
||||
echo "Good $*"; \
|
||||
rm $*.tmp; \
|
||||
else \
|
||||
echo "\033[1;33m Bad $*\033[0m"; \
|
||||
echo "\033[1;34m See $*.tmp\033[0m"; \
|
||||
fi
|
||||
|
||||
# Check all files and error if any ToC were modified.
|
||||
_check_toc: $(MARKDOWN_FILES:=.toc)
|
||||
@[ "$$(find . -name '*.md.tmp' -print -quit)" ] && exit 1 || exit 0
|
||||
|
||||
# Check for mistakes.
|
||||
lint: pyspec _check_toc
|
||||
lint: pyspec
|
||||
@$(MDFORMAT_VENV) --number $(MARKDOWN_FILES)
|
||||
@$(CODESPELL_VENV) . --skip "./.git,$(VENV),$(PYSPEC_DIR)/.mypy_cache" -I .codespell-whitelist
|
||||
@$(PYTHON_VENV) -m flake8 --config $(FLAKE8_CONFIG) $(PYSPEC_DIR)/eth2spec
|
||||
@$(PYTHON_VENV) -m flake8 --config $(FLAKE8_CONFIG) $(TEST_GENERATORS_DIR)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
# How to add a new feature proposal in consensus-specs
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [A. Make it executable for linter checks](#a-make-it-executable-for-linter-checks)
|
||||
- [1. Create a folder under `./specs/_features`](#1-create-a-folder-under-specs_features)
|
||||
@@ -22,7 +19,7 @@
|
||||
- [Bonus](#bonus)
|
||||
- [Need help?](#need-help)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## A. Make it executable for linter checks
|
||||
|
||||
@@ -38,11 +35,6 @@ For example, if the latest fork is Capella, use `./specs/capella` content as you
|
||||
|
||||
- You can either use [Beacon Chain Spec Template](./templates/beacon-chain-template.md), or make a copy of the latest fork content and then edit it.
|
||||
- Tips:
|
||||
- We use [`doctoc`](https://www.npmjs.com/package/doctoc) tool to generate the table of content.
|
||||
```
|
||||
cd consensus-specs
|
||||
doctoc specs
|
||||
```
|
||||
- The differences between "Constants", "Configurations", and "Presets":
|
||||
- Constants: The constant that should never be changed.
|
||||
- Configurations: The settings that we may change for different networks.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Release Procedure
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Open a Release Pull Request](#open-a-release-pull-request)
|
||||
@@ -21,8 +17,7 @@
|
||||
- [Click the Release Buttons](#click-the-release-buttons)
|
||||
- [Make an Announcement](#make-an-announcement)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
9
docs/docs/templates/beacon-chain-template.md
vendored
9
docs/docs/templates/beacon-chain-template.md
vendored
@@ -2,14 +2,9 @@
|
||||
|
||||
# <FORK_NAME> -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
# Fork Choice -- Safe Block
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [`get_safe_beacon_block_root`](#get_safe_beacon_block_root)
|
||||
- [`get_safe_execution_block_hash`](#get_safe_execution_block_hash)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ test = [
|
||||
lint = [
|
||||
"codespell==2.4.1",
|
||||
"flake8==7.2.0",
|
||||
"mdformat-gfm-alerts==1.0.1",
|
||||
"mdformat-gfm==0.4.1",
|
||||
"mdformat-toc==0.3.0",
|
||||
"mdformat==0.7.22",
|
||||
"mypy==1.15.0",
|
||||
"pylint==3.3.6",
|
||||
]
|
||||
|
||||
@@ -31,6 +31,3 @@ OPTIMIZED_BLS_AGGREGATE_PUBKEYS = '''
|
||||
def eth_aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
|
||||
return bls.AggregatePKs(pubkeys)
|
||||
'''
|
||||
|
||||
|
||||
ETH2_SPEC_COMMENT_PREFIX = "eth2spec:"
|
||||
|
||||
19
setup.py
19
setup.py
@@ -11,7 +11,7 @@ from collections import OrderedDict
|
||||
from distutils import dir_util
|
||||
from distutils.util import convert_path
|
||||
from functools import lru_cache
|
||||
from marko.block import Heading, FencedCode, LinkRefDef, BlankLine
|
||||
from marko.block import Heading, FencedCode, HTMLBlock, BlankLine
|
||||
from marko.ext.gfm import gfm
|
||||
from marko.ext.gfm.elements import Table
|
||||
from marko.inline import CodeSpan
|
||||
@@ -26,7 +26,6 @@ sys.path.insert(0, pysetup_path)
|
||||
|
||||
from pysetup.constants import (
|
||||
PHASE0,
|
||||
ETH2_SPEC_COMMENT_PREFIX,
|
||||
)
|
||||
from pysetup.helpers import (
|
||||
combine_spec_objects,
|
||||
@@ -149,17 +148,6 @@ ALL_CURDLEPROOFS_CRS = {
|
||||
}
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _get_eth2_spec_comment(child: LinkRefDef) -> Optional[str]:
|
||||
title = child.title
|
||||
if not (title[0] == "(" and title[len(title)-1] == ")"):
|
||||
return None
|
||||
title = title[1:len(title)-1]
|
||||
if not title.startswith(ETH2_SPEC_COMMENT_PREFIX):
|
||||
return None
|
||||
return title[len(ETH2_SPEC_COMMENT_PREFIX):].strip()
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _parse_value(name: str, typed_value: str, type_hint: Optional[str] = None) -> VariableDefinition:
|
||||
comment = None
|
||||
@@ -324,9 +312,8 @@ def get_spec(file_name: Path, preset: Dict[str, str], config: Dict[str, str], pr
|
||||
else:
|
||||
constant_vars[name] = value_def
|
||||
|
||||
elif isinstance(child, LinkRefDef):
|
||||
comment = _get_eth2_spec_comment(child)
|
||||
if comment == "skip":
|
||||
elif isinstance(child, HTMLBlock):
|
||||
if child.body.strip() == "<!-- eth2spec: skip -->":
|
||||
should_skip = True
|
||||
|
||||
# Load KZG trusted setup from files
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -52,8 +48,7 @@
|
||||
- [Handling of reveal deadlines](#handling-of-reveal-deadlines)
|
||||
- [Final updates](#final-updates)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -64,55 +59,55 @@ building upon the [Sharding](../sharding/beacon-chain.md) specification.
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Unit |
|
||||
| - | - | - |
|
||||
| `CUSTODY_PRIME` | `int(2 ** 256 - 189)` | - |
|
||||
| `CUSTODY_SECRETS` | `uint64(3)` | - |
|
||||
| `BYTES_PER_CUSTODY_ATOM` | `uint64(32)` | bytes |
|
||||
| `CUSTODY_PROBABILITY_EXPONENT` | `uint64(10)` | - |
|
||||
| Name | Value | Unit |
|
||||
| ------------------------------ | --------------------- | ----- |
|
||||
| `CUSTODY_PRIME` | `int(2 ** 256 - 189)` | - |
|
||||
| `CUSTODY_SECRETS` | `uint64(3)` | - |
|
||||
| `BYTES_PER_CUSTODY_ATOM` | `uint64(32)` | bytes |
|
||||
| `CUSTODY_PROBABILITY_EXPONENT` | `uint64(10)` | - |
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ----------------------------- | -------------------------- |
|
||||
| `DOMAIN_CUSTODY_BIT_SLASHING` | `DomainType('0x83000000')` |
|
||||
|
||||
## Preset
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| `RANDAO_PENALTY_EPOCHS` | `uint64(2**1)` (= 2) | epochs | 12.8 minutes |
|
||||
| `EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||
| `EPOCHS_PER_CUSTODY_PERIOD` | `uint64(2**14)` (= 16,384) | epochs | ~73 days |
|
||||
| `CUSTODY_PERIOD_TO_RANDAO_PADDING` | `uint64(2**11)` (= 2,048) | epochs | ~9 days |
|
||||
| `MAX_CHUNK_CHALLENGE_DELAY` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ------------------------------------------------ | -------------------------- | :----: | :----------: |
|
||||
| `RANDAO_PENALTY_EPOCHS` | `uint64(2**1)` (= 2) | epochs | 12.8 minutes |
|
||||
| `EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||
| `EPOCHS_PER_CUSTODY_PERIOD` | `uint64(2**14)` (= 16,384) | epochs | ~73 days |
|
||||
| `CUSTODY_PERIOD_TO_RANDAO_PADDING` | `uint64(2**11)` (= 2,048) | epochs | ~9 days |
|
||||
| `MAX_CHUNK_CHALLENGE_DELAY` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RECORDS` | `uint64(2**20)` (= 1,048,576) |
|
||||
| `MAX_CUSTODY_KEY_REVEALS` | `uint64(2**8)` (= 256) |
|
||||
| `MAX_EARLY_DERIVED_SECRET_REVEALS` | `uint64(2**0)` (= 1) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGES` | `uint64(2**2)` (= 4) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES` | `uint64(2**4)` (= 16) |
|
||||
| `MAX_CUSTODY_SLASHINGS` | `uint64(2**0)` (= 1) |
|
||||
| Name | Value |
|
||||
| --------------------------------------- | ----------------------------- |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RECORDS` | `uint64(2**20)` (= 1,048,576) |
|
||||
| `MAX_CUSTODY_KEY_REVEALS` | `uint64(2**8)` (= 256) |
|
||||
| `MAX_EARLY_DERIVED_SECRET_REVEALS` | `uint64(2**0)` (= 1) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGES` | `uint64(2**2)` (= 4) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES` | `uint64(2**4)` (= 16) |
|
||||
| `MAX_CUSTODY_SLASHINGS` | `uint64(2**0)` (= 1) |
|
||||
|
||||
### Size parameters
|
||||
|
||||
| Name | Value | Unit |
|
||||
| - | - | - |
|
||||
| `BYTES_PER_CUSTODY_CHUNK` | `uint64(2**12)` (= 4,096) | bytes |
|
||||
| `CUSTODY_RESPONSE_DEPTH` | `ceillog2(MAX_SHARD_BLOCK_SIZE // BYTES_PER_CUSTODY_CHUNK)` | - |
|
||||
| Name | Value | Unit |
|
||||
| ------------------------- | ----------------------------------------------------------- | ----- |
|
||||
| `BYTES_PER_CUSTODY_CHUNK` | `uint64(2**12)` (= 4,096) | bytes |
|
||||
| `CUSTODY_RESPONSE_DEPTH` | `ceillog2(MAX_SHARD_BLOCK_SIZE // BYTES_PER_CUSTODY_CHUNK)` | - |
|
||||
|
||||
### Reward and penalty quotients
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE` | `uint64(2**1)` (= 2) |
|
||||
| `MINOR_REWARD_QUOTIENT` | `uint64(2**8)` (= 256) |
|
||||
| Name | Value |
|
||||
| -------------------------------------------------- | ---------------------- |
|
||||
| `EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE` | `uint64(2**1)` (= 2) |
|
||||
| `MINOR_REWARD_QUOTIENT` | `uint64(2**8)` (= 256) |
|
||||
|
||||
## Data structures
|
||||
|
||||
|
||||
@@ -2,25 +2,20 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Becoming a validator](#becoming-a-validator)
|
||||
- [Beacon chain validator assignments](#beacon-chain-validator-assignments)
|
||||
- [Custody slashings](#custody-slashings)
|
||||
- [Custody key reveals](#custody-key-reveals)
|
||||
- [Early derived secret reveals](#early-derived-secret-reveals)
|
||||
- [Construct attestation](#construct-attestation)
|
||||
- [Custody slashings](#custody-slashings)
|
||||
- [Custody key reveals](#custody-key-reveals)
|
||||
- [Early derived secret reveals](#early-derived-secret-reveals)
|
||||
- [Construct attestation](#construct-attestation)
|
||||
- [How to avoid slashing](#how-to-avoid-slashing)
|
||||
- [Custody slashing](#custody-slashing)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Custom types](#custom-types)
|
||||
- [Configuration](#configuration)
|
||||
@@ -21,23 +17,22 @@
|
||||
- [Data recovery](#data-recovery)
|
||||
- [DAS functions](#das-functions)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Custom types
|
||||
|
||||
We define the following Python custom types for type hinting and readability:
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `SampleIndex` | `uint64` | A sample index, corresponding to chunk of extended data |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ------------- | -------------- | ------------------------------------------------------- |
|
||||
| `SampleIndex` | `uint64` | A sample index, corresponding to chunk of extended data |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Notes |
|
||||
| - | - | - |
|
||||
| Name | Value | Notes |
|
||||
| ------------------- | --------------- | ----------------------------------------------------------------- |
|
||||
| `MAX_RESAMPLE_TIME` | `TODO` (= TODO) | Time window to sample a shard blob and put it on vertical subnets |
|
||||
|
||||
## New containers
|
||||
@@ -80,6 +75,7 @@ def reverse_bit_order_list(elements: Sequence[int]) -> Sequence[int]:
|
||||
### Data extension
|
||||
|
||||
Implementations:
|
||||
|
||||
- [Python](https://github.com/protolambda/partial_fft/blob/master/das_fft.py)
|
||||
- [Go](https://github.com/protolambda/go-kate/blob/master/das_extension.go)
|
||||
|
||||
@@ -95,8 +91,9 @@ def das_fft_extension(data: Sequence[Point]) -> Sequence[Point]:
|
||||
|
||||
### Data recovery
|
||||
|
||||
See [Reed-Solomon erasure code recovery in n*log^2(n) time with FFTs](https://ethresear.ch/t/reed-solomon-erasure-code-recovery-in-n-log-2-n-time-with-ffts/3039) for theory.
|
||||
See [Reed-Solomon erasure code recovery in `n*log^2(n)` time with FFTs](https://ethresear.ch/t/reed-solomon-erasure-code-recovery-in-n-log-2-n-time-with-ffts/3039) for theory.
|
||||
Implementations:
|
||||
|
||||
- [Original Python](https://github.com/ethereum/research/blob/master/mimc_stark/recovery.py)
|
||||
- [New optimized approach in python](https://github.com/ethereum/research/tree/master/polynomial_reconstruction)
|
||||
- [Old approach in Go](https://github.com/protolambda/go-kzg/blob/master/legacy_recovery.go)
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Dependency calculation](#dependency-calculation)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [DAS Subnets](#das-subnets)
|
||||
@@ -25,8 +21,7 @@
|
||||
- [Messages](#messages)
|
||||
- [DASQuery](#dasquery)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -144,9 +139,10 @@ If the node does not already have connected peers on the topic it needs to sampl
|
||||
### Topics and messages
|
||||
|
||||
Following the same scheme as the [Phase0 gossip topics](../../phase0/p2p-interface.md#topics-and-messages), names and payload types are:
|
||||
| Name | Message Type |
|
||||
|----------------------------------|---------------------------|
|
||||
| `das_sample_{subnet_index}` | `DASSample` |
|
||||
|
||||
| Name | Message Type |
|
||||
| --------------------------- | ------------ |
|
||||
| `das_sample_{subnet_index}` | `DASSample` |
|
||||
|
||||
Also see the [Sharding general networking spec](../sharding/p2p-interface.md) for important topics such as that of the shard-blobs and shard-headers.
|
||||
|
||||
@@ -157,6 +153,7 @@ Extending the regular `shard_blob_{shard}` as [defined in the Sharding networkin
|
||||
If participating in DAS, upon receiving a `signed_blob` for the first time with a `slot` not older than `MAX_RESAMPLE_TIME`,
|
||||
a subscriber of a `shard_blob_{shard}` SHOULD reconstruct the samples and publish them to vertical subnets.
|
||||
Take `blob = signed_blob.blob`:
|
||||
|
||||
1. Extend the data: `extended_data = extend_data(blob.data)`
|
||||
2. Create samples with proofs: `samples = sample_data(blob.slot, blob.shard, extended_data)`
|
||||
3. Fanout-publish the samples to the vertical subnets of its peers (not all vertical subnets may be reached).
|
||||
@@ -171,12 +168,12 @@ against the commitment to blob polynomial, specific to that `(shard, slot)` key.
|
||||
The following validations MUST pass before forwarding the `sample` on the vertical subnet.
|
||||
|
||||
- _[IGNORE]_ The commitment for the (`sample.shard`, `sample.slot`, `sample.index`) tuple must be known.
|
||||
If not known, the client MAY queue the sample if it passes formatting conditions.
|
||||
If not known, the client MAY queue the sample if it passes formatting conditions.
|
||||
- _[REJECT]_ `sample.shard`, `sample.slot` and `sample.index` are hashed into a `sbunet_index` (TODO: define hash) which MUST match the topic `{subnet_index}` parameter.
|
||||
- _[REJECT]_ `sample.shard` must be within valid range: `0 <= sample.shard < get_active_shard_count(state, compute_epoch_at_slot(sample.slot))`.
|
||||
- _[REJECT]_ `sample.index` must be within valid range: `0 <= sample.index < sample_count`, where:
|
||||
- `sample_count = (points_count + POINTS_PER_SAMPLE - 1) // POINTS_PER_SAMPLE`
|
||||
- `points_count` is the length as claimed along with the commitment, which must be smaller than `MAX_SAMPLES_PER_BLOCK`.
|
||||
- `sample_count = (points_count + POINTS_PER_SAMPLE - 1) // POINTS_PER_SAMPLE`
|
||||
- `points_count` is the length as claimed along with the commitment, which must be smaller than `MAX_SAMPLES_PER_BLOCK`.
|
||||
- _[IGNORE]_ The `sample` is not from a future slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. validate that `sample.slot <= current_slot`. A client MAY queue future samples for processing at the appropriate slot if it passed formatting conditions.
|
||||
- _[IGNORE]_ This is the first received sample with the (`sample.shard`, `sample.slot`, `sample.index`) key tuple.
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Data Availability Sampling](#data-availability-sampling)
|
||||
- [GossipSub](#gossipsub)
|
||||
@@ -19,8 +15,7 @@
|
||||
- [Stage 1: Pulling missing samples from known peers](#stage-1-pulling-missing-samples-from-known-peers)
|
||||
- [Stage 2: Pulling missing data from validators with custody.](#stage-2-pulling-missing-data-from-validators-with-custody)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Data Availability Sampling
|
||||
|
||||
@@ -54,6 +49,7 @@ In such event, a node can move through below stages until it recovers data avail
|
||||
Wait for the sample to re-broadcast. Someone may be slow with publishing, or someone else is able to do the work.
|
||||
|
||||
Any node can do the following work to keep the network healthy:
|
||||
|
||||
- Common: Listen on a horizontal subnet, chunkify the block data in samples, and propagate the samples to vertical subnets.
|
||||
- Extreme: Listen on enough vertical subnets, reconstruct the missing samples by recovery, and propagate the recovered samples.
|
||||
|
||||
@@ -68,6 +64,7 @@ without explicitly asking for the data.
|
||||
However, *network identities* are still used to build a backbone for each vertical subnet.
|
||||
These nodes should have received the samples, and can serve a buffer of them on demand.
|
||||
Although serving these is not directly incentivised, it is little work:
|
||||
|
||||
1. Buffer any message you see on the backbone vertical subnets, for a buffer of up to two weeks.
|
||||
2. Serve the samples on request. An individual sample is just expected to be `~ 0.5 KB`, and does not require any pre-processing to serve.
|
||||
|
||||
@@ -79,4 +76,3 @@ TODO: detailed failure-mode spec. Stop after trying e.g. 3 peers for any sample
|
||||
|
||||
Pulling samples directly from nodes with validators that have a custody responsibility,
|
||||
without revealing their identity to the network, is an open problem.
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Glossary](#glossary)
|
||||
@@ -42,8 +38,7 @@
|
||||
- [Sharded data](#sharded-data)
|
||||
- [Execution payload](#execution-payload)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -62,38 +57,38 @@ The following values are (non-configurable) constants used throughout the specif
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Notes |
|
||||
| - | - | - |
|
||||
| Name | Value | Notes |
|
||||
| --------------------------- | --------------------- | ------------------- |
|
||||
| `FIELD_ELEMENTS_PER_SAMPLE` | `uint64(2**4)` (= 16) | 31 * 16 = 496 bytes |
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| --------------------- | -------------------------- |
|
||||
| `DOMAIN_SHARD_SAMPLE` | `DomainType('0x10000000')` |
|
||||
|
||||
## Preset
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Notes |
|
||||
| - | - | - |
|
||||
| `MAX_SHARDS` | `uint64(2**12)` (= 4,096) | Theoretical max shard count (used to determine data structure sizes) |
|
||||
| `ACTIVE_SHARDS` | `uint64(2**8)` (= 256) | Initial shard count |
|
||||
| `MAX_PROPOSER_BLOCKS_BETWEEN_BUILDER_BLOCKS` | `uint64(2**4)` (= 16) | TODO: Need to define what happens if there were more blocks without builder blocks |
|
||||
| Name | Value | Notes |
|
||||
| -------------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| `MAX_SHARDS` | `uint64(2**12)` (= 4,096) | Theoretical max shard count (used to determine data structure sizes) |
|
||||
| `ACTIVE_SHARDS` | `uint64(2**8)` (= 256) | Initial shard count |
|
||||
| `MAX_PROPOSER_BLOCKS_BETWEEN_BUILDER_BLOCKS` | `uint64(2**4)` (= 16) | TODO: Need to define what happens if there were more blocks without builder blocks |
|
||||
|
||||
### Time parameters
|
||||
|
||||
With the introduction of builder blocks the number of slots per epoch is doubled (it counts beacon blocks and builder blocks).
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ----------------- | --------------------- | :---: | :----------: |
|
||||
| `SLOTS_PER_EPOCH` | `uint64(2**6)` (= 64) | slots | 8:32 minutes |
|
||||
|
||||
### Shard blob samples
|
||||
|
||||
| Name | Value | Notes |
|
||||
| - | - | - |
|
||||
| Name | Value | Notes |
|
||||
| ------------------ | ---------------------- | ------------------------- |
|
||||
| `SAMPLES_PER_BLOB` | `uint64(2**9)` (= 512) | 248 * 512 = 126,976 bytes |
|
||||
|
||||
## Configuration
|
||||
@@ -103,8 +98,8 @@ E.g. `ACTIVE_SHARDS` and `SAMPLES_PER_BLOB`.
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ------------------ | ----------- | :-----: | :-------: |
|
||||
| `SECONDS_PER_SLOT` | `uint64(8)` | seconds | 8 seconds |
|
||||
|
||||
## Containers
|
||||
@@ -409,4 +404,4 @@ def process_execution_payload(state: BeaconState, block: BeaconBlock, execution_
|
||||
block_hash=payload.block_hash,
|
||||
transactions_root=hash_tree_root(payload.transactions),
|
||||
)
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -18,8 +14,7 @@
|
||||
- [Shard sample subnets](#shard-sample-subnets)
|
||||
- [`shard_row_{subnet_id}`](#shard_row_subnet_id)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -41,11 +36,11 @@ The adjustments and additions for Shards are outlined in this document.
|
||||
|
||||
Following the same scheme as the [Phase0 gossip topics](../../phase0/p2p-interface.md#topics-and-messages), names and payload types are:
|
||||
|
||||
| Name | Message Type |
|
||||
|---------------------------------|--------------------------|
|
||||
| `shard_row_{subnet_id}` | `SignedShardSample` |
|
||||
| `shard_column_{subnet_id}` | `SignedShardSample` |
|
||||
| `builder_block_bid` | `BuilderBlockBid` |
|
||||
| Name | Message Type |
|
||||
| -------------------------- | ------------------- |
|
||||
| `shard_row_{subnet_id}` | `SignedShardSample` |
|
||||
| `shard_column_{subnet_id}` | `SignedShardSample` |
|
||||
| `builder_block_bid` | `BuilderBlockBid` |
|
||||
|
||||
The [DAS network specification](../das/das-core.md) defines additional topics.
|
||||
|
||||
@@ -88,4 +83,3 @@ The following validations MUST pass before forwarding the `sample`.
|
||||
- _[REJECT]_ The sample signature, `sample.signature`, is valid for the builder --
|
||||
i.e. `bls.Verify(builder_pubkey, sample_signing_root, sample.signature)` OR `sample.signature == Bytes96(b"\0" * 96)` AND
|
||||
the sample verification `verify_sample` passes
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -14,9 +10,9 @@
|
||||
- [KZG Trusted setup](#kzg-trusted-setup)
|
||||
- [Custom types](#custom-types)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [`next_power_of_two`](#next_power_of_two)
|
||||
- [`reverse_bit_order`](#reverse_bit_order)
|
||||
- [`list_to_reverse_bit_order`](#list_to_reverse_bit_order)
|
||||
- [`next_power_of_two`](#next_power_of_two)
|
||||
- [`reverse_bit_order`](#reverse_bit_order)
|
||||
- [`list_to_reverse_bit_order`](#list_to_reverse_bit_order)
|
||||
- [Field operations](#field-operations)
|
||||
- [Generic field operations](#generic-field-operations)
|
||||
- [`bls_modular_inverse`](#bls_modular_inverse)
|
||||
@@ -27,10 +23,10 @@
|
||||
- [`vector_lincomb`](#vector_lincomb)
|
||||
- [`bytes_to_field_elements`](#bytes_to_field_elements)
|
||||
- [Polynomial operations](#polynomial-operations)
|
||||
- [`add_polynomials`](#add_polynomials)
|
||||
- [`multiply_polynomials`](#multiply_polynomials)
|
||||
- [`interpolate_polynomial`](#interpolate_polynomial)
|
||||
- [`evaluate_polynomial_in_evaluation_form`](#evaluate_polynomial_in_evaluation_form)
|
||||
- [`add_polynomials`](#add_polynomials)
|
||||
- [`multiply_polynomials`](#multiply_polynomials)
|
||||
- [`interpolate_polynomial`](#interpolate_polynomial)
|
||||
- [`evaluate_polynomial_in_evaluation_form`](#evaluate_polynomial_in_evaluation_form)
|
||||
- [KZG Operations](#kzg-operations)
|
||||
- [Elliptic curve helper functions](#elliptic-curve-helper-functions)
|
||||
- [`elliptic_curve_lincomb`](#elliptic_curve_lincomb)
|
||||
@@ -41,8 +37,7 @@
|
||||
- [`verify_kzg_multiproof`](#verify_kzg_multiproof)
|
||||
- [`verify_degree_proof`](#verify_degree_proof)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -52,28 +47,28 @@ This document specifies basic polynomial operations and KZG polynomial commitmen
|
||||
|
||||
### BLS Field
|
||||
|
||||
| Name | Value | Notes |
|
||||
| - | - | - |
|
||||
| `BLS_MODULUS` | `0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001` (curve order of BLS12_381) |
|
||||
| `PRIMITIVE_ROOT_OF_UNITY` | `7` | Primitive root of unity of the BLS12_381 (inner) BLS_MODULUS |
|
||||
| Name | Value | Notes |
|
||||
| ------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| `BLS_MODULUS` | `0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001` (curve order of BLS12_381) | |
|
||||
| `PRIMITIVE_ROOT_OF_UNITY` | `7` | Primitive root of unity of the BLS12_381 (inner) BLS_MODULUS |
|
||||
|
||||
### KZG Trusted setup
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ---------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `G1_SETUP` | Type `List[G1]`. The G1-side trusted setup `[G, G*s, G*s**2....]`; note that the first point is the generator. |
|
||||
| `G2_SETUP` | Type `List[G2]`. The G2-side trusted setup `[G, G*s, G*s**2....]` |
|
||||
| `G2_SETUP` | Type `List[G2]`. The G2-side trusted setup `[G, G*s, G*s**2....]` |
|
||||
|
||||
## Custom types
|
||||
|
||||
We define the following Python custom types for type hinting and readability:
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `KZGCommitment` | `Bytes48` | A G1 curve point |
|
||||
| `BLSFieldElement` | `uint256` | A number `x` in the range `0 <= x < BLS_MODULUS` |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ----------------------------- | ----------------------- | ---------------------------------------------------------- |
|
||||
| `KZGCommitment` | `Bytes48` | A G1 curve point |
|
||||
| `BLSFieldElement` | `uint256` | A number `x` in the range `0 <= x < BLS_MODULUS` |
|
||||
| `BLSPolynomialByCoefficients` | `List[BLSFieldElement]` | A polynomial over the BLS field, given in coefficient form |
|
||||
| `BLSPolynomialByEvaluations` | `List[BLSFieldElement]` | A polynomial over the BLS field, given in evaluation form |
|
||||
| `BLSPolynomialByEvaluations` | `List[BLSFieldElement]` | A polynomial over the BLS field, given in evaluation form |
|
||||
|
||||
## Helper functions
|
||||
|
||||
@@ -391,4 +386,4 @@ def verify_degree_proof(commitment: KZGCommitment, degree_bound: uint64, proof:
|
||||
bls.Pairing(proof, G2_SETUP[0])
|
||||
== bls.Pairing(commitment, G2_SETUP[-degree_bound])
|
||||
)
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,30 +2,23 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Constants](#constants)
|
||||
- [Sample counts](#sample-counts)
|
||||
- [Helpers](#helpers)
|
||||
- [`get_validator_row_subnets`](#get_validator_row_subnets)
|
||||
- [`get_validator_column_subnets`](#get_validator_column_subnets)
|
||||
- [`reconstruct_polynomial`](#reconstruct_polynomial)
|
||||
- [Sample verification](#sample-verification)
|
||||
- [`verify_sample`](#verify_sample)
|
||||
- [Validator assignments](#validator-assignments)
|
||||
- [Attesting](#attesting)
|
||||
- [Minimum online validator requirement](#minimum-online-validator-requirement)
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Constants](#constants)
|
||||
- [Sample counts](#sample-counts)
|
||||
- [Helpers](#helpers)
|
||||
- [`get_validator_row_subnets`](#get_validator_row_subnets)
|
||||
- [`get_validator_column_subnets`](#get_validator_column_subnets)
|
||||
- [`reconstruct_polynomial`](#reconstruct_polynomial)
|
||||
- [Sample verification](#sample-verification)
|
||||
- [`verify_sample`](#verify_sample)
|
||||
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
|
||||
- [Validator assignments](#validator-assignments)
|
||||
- [Attesting](#attesting)
|
||||
- [Sample reconstruction](#sample-reconstruction)
|
||||
- [Minimum online validator requirement](#minimum-online-validator-requirement)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -43,10 +36,10 @@ Please see related Beacon Chain doc before continuing and use them as a referenc
|
||||
|
||||
### Sample counts
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `VALIDATOR_SAMPLE_ROW_COUNT` | `2` |
|
||||
| `VALIDATOR_SAMPLE_COLUMN_COUNT` | `2` |
|
||||
| Name | Value |
|
||||
| ------------------------------- | ----- |
|
||||
| `VALIDATOR_SAMPLE_ROW_COUNT` | `2` |
|
||||
| `VALIDATOR_SAMPLE_COLUMN_COUNT` | `2` |
|
||||
|
||||
## Helpers
|
||||
|
||||
@@ -113,7 +106,7 @@ A row or column is *available* for a `slot` if at least half of the total number
|
||||
|
||||
If a validator is assigned to an attestation at slot `attestation_slot` and had his previous attestation duty at `previous_attestation_slot`, then they should only attest under the following conditions:
|
||||
|
||||
* For all intermediate blocks `block` with `previous_attestation_slot < block.slot <= attestation_slot`: All sample rows and columns assigned to the validator were available.
|
||||
- For all intermediate blocks `block` with `previous_attestation_slot < block.slot <= attestation_slot`: All sample rows and columns assigned to the validator were available.
|
||||
|
||||
If this condition is not fulfilled, then the validator should instead attest to the last block for which the condition holds.
|
||||
|
||||
@@ -126,9 +119,9 @@ A validator that has received enough samples of a row or column to mark it as av
|
||||
Once they have run the reconstruction function, they should distribute the samples that they reconstructed on all pubsub that
|
||||
the local node is subscribed to, if they have not already received that sample on that pubsub. As an example:
|
||||
|
||||
* The validator is subscribed to row `2` and column `5`
|
||||
* The sample `(row, column) = (2, 5)` is missing in the column `5` pubsub
|
||||
* After they have reconstruction of row `2`, the validator should send the sample `(2, 5)` on to the row `2` pubsub (if it was missing) as well as the column `5` pubsub.
|
||||
- The validator is subscribed to row `2` and column `5`
|
||||
- The sample `(row, column) = (2, 5)` is missing in the column `5` pubsub
|
||||
- After they have reconstruction of row `2`, the validator should send the sample `(2, 5)` on to the row `2` pubsub (if it was missing) as well as the column `5` pubsub.
|
||||
|
||||
TODO: We need to verify the total complexity of doing this and make sure this does not cause too much load on a validator
|
||||
|
||||
@@ -138,4 +131,4 @@ The data availability construction guarantees that reconstruction is possible if
|
||||
|
||||
Each validator will transfer 4 samples between rows and columns where there is overlap. Without loss of generality, look at row 0. Each validator has 1/128 chance of having a sample in this row, and we need 256 samples to reconstruct it. So we expect that we need ~256 * 128 = 32,768 validators to have a fair chance of reconstructing it if it was completely unseeded.
|
||||
|
||||
A more elaborate estimate [here](https://notes.ethereum.org/@dankrad/minimum-reconstruction-validators) needs about 55,000 validators to be online for high safety that each row and column will be reconstructed.
|
||||
A more elaborate estimate [here](https://notes.ethereum.org/@dankrad/minimum-reconstruction-validators) needs about 55,000 validators to be online for high safety that each row and column will be reconstructed.
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -28,8 +24,7 @@
|
||||
- [`process_execution_payload`](#process_execution_payload)
|
||||
- [Testing](#testing)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -37,22 +32,22 @@ This upgrade adds transaction execution to the beacon chain as part of the eip68
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `BanderwagonGroupElement` | `Bytes32` | |
|
||||
| `BanderwagonFieldElement` | `Bytes32` | |
|
||||
| `Stem` | `Bytes31` | |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ------------------------- | -------------- | ----------- |
|
||||
| `BanderwagonGroupElement` | `Bytes32` | |
|
||||
| `BanderwagonFieldElement` | `Bytes32` | |
|
||||
| `Stem` | `Bytes31` | |
|
||||
|
||||
## Preset
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_STEMS` | `uint64(2**16)` (= 65,536) |
|
||||
| `MAX_COMMITMENTS_PER_STEM` | `uint64(33)` |
|
||||
| `VERKLE_WIDTH` | `uint64(2**8)` (= 256) |
|
||||
| `IPA_PROOF_DEPTH` | `uint64(2**3)` (= 8) |
|
||||
| Name | Value |
|
||||
| -------------------------- | -------------------------- |
|
||||
| `MAX_STEMS` | `uint64(2**16)` (= 65,536) |
|
||||
| `MAX_COMMITMENTS_PER_STEM` | `uint64(33)` |
|
||||
| `VERKLE_WIDTH` | `uint64(2**8)` (= 256) |
|
||||
| `IPA_PROOF_DEPTH` | `uint64(2**3)` (= 8) |
|
||||
|
||||
## Containers
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -17,8 +13,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -28,10 +23,10 @@ This document describes the process of the eip6800 upgrade.
|
||||
|
||||
Warning: this configuration is not definitive.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `EIP6800_FORK_VERSION` | `Version('0x05000000')` |
|
||||
| `EIP6800_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
| Name | Value |
|
||||
| ---------------------- | ------------------------------------- |
|
||||
| `EIP6800_FORK_VERSION` | `Version('0x05000000')` |
|
||||
| `EIP6800_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Preset](#preset)
|
||||
@@ -18,8 +14,7 @@
|
||||
- [Block processing](#block-processing)
|
||||
- [Modified `get_index_for_new_validator`](#modified-get_index_for_new_validator)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -31,8 +26,8 @@ This is the beacon chain specification to assign new deposits to existing valida
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | - | - |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ---------------------------- | -------------------------- | ------ | --------- |
|
||||
| `SAFE_EPOCHS_TO_REUSE_INDEX` | `uint64(2**16)` (= 65,536) | epochs | ~0.8 year |
|
||||
|
||||
## Helper functions
|
||||
|
||||
@@ -2,19 +2,14 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Fork choice](#fork-choice)
|
||||
- [Handlers](#handlers)
|
||||
- [`on_reused_index`](#on_reused_index)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -26,8 +22,7 @@
|
||||
- [Deposits](#deposits)
|
||||
- [`get_beacon_proposer_index`](#get_beacon_proposer_index)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -47,21 +42,21 @@ This document details the beacon chain additions and changes of to support the E
|
||||
|
||||
## Preset
|
||||
|
||||
| Name | Value | Description |
|
||||
| -------------------------- | -------------------------- | ----------------------------------------------------------- |
|
||||
| `CURDLEPROOFS_N_BLINDERS` | `uint64(4)` | number of blinders for curdleproofs |
|
||||
| `CANDIDATE_TRACKERS_COUNT` | `uint64(2**14)` (= 16,384) | number of candidate trackers |
|
||||
| `PROPOSER_TRACKERS_COUNT` | `uint64(2**13)` (= 8,192) | number of proposer trackers |
|
||||
| `VALIDATORS_PER_SHUFFLE` | `uint64(2**7 - 4)` (= 124) | number of validators shuffled per shuffle step |
|
||||
| `MAX_SHUFFLE_PROOF_SIZE` | `uint64(2**15)` | max size of a shuffle proof |
|
||||
| `MAX_OPENING_PROOF_SIZE` | `uint64(2**10)` | max size of an opening proof |
|
||||
| Name | Value | Description |
|
||||
| -------------------------- | -------------------------- | ---------------------------------------------- |
|
||||
| `CURDLEPROOFS_N_BLINDERS` | `uint64(4)` | number of blinders for curdleproofs |
|
||||
| `CANDIDATE_TRACKERS_COUNT` | `uint64(2**14)` (= 16,384) | number of candidate trackers |
|
||||
| `PROPOSER_TRACKERS_COUNT` | `uint64(2**13)` (= 8,192) | number of proposer trackers |
|
||||
| `VALIDATORS_PER_SHUFFLE` | `uint64(2**7 - 4)` (= 124) | number of validators shuffled per shuffle step |
|
||||
| `MAX_SHUFFLE_PROOF_SIZE` | `uint64(2**15)` | max size of a shuffle proof |
|
||||
| `MAX_OPENING_PROOF_SIZE` | `uint64(2**10)` | max size of an opening proof |
|
||||
|
||||
## Configuration
|
||||
|
||||
| Name | Value | Description |
|
||||
| ---------------------------------- | -------------------------- | ----------------------------------------------------------- |
|
||||
| `EPOCHS_PER_SHUFFLING_PHASE` | `Epoch(2**8)` (= 256) | epochs per shuffling phase |
|
||||
| `PROPOSER_SELECTION_GAP` | `Epoch(2)` | gap between proposer selection and the block proposal phase |
|
||||
| Name | Value | Description |
|
||||
| ---------------------------- | --------------------- | ----------------------------------------------------------- |
|
||||
| `EPOCHS_PER_SHUFFLING_PHASE` | `Epoch(2**8)` (= 256) | epochs per shuffling phase |
|
||||
| `PROPOSER_SELECTION_GAP` | `Epoch(2)` | gap between proposer selection and the block proposal phase |
|
||||
|
||||
## Cryptography
|
||||
|
||||
@@ -91,11 +86,11 @@ def bytes_to_bls_field(b: Bytes32) -> BLSFieldElement:
|
||||
return BLSFieldElement(field_element % BLS_MODULUS)
|
||||
```
|
||||
|
||||
| Name | Value |
|
||||
| --------------------- | ------------------------------------------------------------------------------- |
|
||||
| `BLS_G1_GENERATOR` | `BLSG1Point('0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb') # noqa: E501` |
|
||||
| `BLS_MODULUS` | `52435875175126190479447740508185965837690552500527637822603658699938581184513` |
|
||||
| `CURDLEPROOFS_CRS` | TBD |
|
||||
| Name | Value |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `BLS_G1_GENERATOR` | `BLSG1Point('0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb') # noqa: E501` |
|
||||
| `BLS_MODULUS` | `52435875175126190479447740508185965837690552500527637822603658699938581184513` |
|
||||
| `CURDLEPROOFS_CRS` | TBD |
|
||||
|
||||
### Curdleproofs and opening proofs
|
||||
|
||||
|
||||
@@ -2,18 +2,13 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
- [Fork to EIP-7441](#fork-to-eip-7441)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -60,8 +56,7 @@
|
||||
- [Testing](#testing)
|
||||
- [Modified `is_merge_transition_complete`](#modified-is_merge_transition_complete-1)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -69,7 +64,7 @@ This is the beacon chain specification of the enshrined proposer builder separat
|
||||
|
||||
*Note*: This specification is built upon [Electra](../../electra/beacon-chain.md) and is under active development.
|
||||
|
||||
This feature adds new staked consensus participants called *Builders* and new honest validators duties called *payload timeliness attestations*. The slot is divided in **four** intervals. Honest validators gather *signed bids* (a `SignedExecutionPayloadHeader`) from builders and submit their consensus blocks (a `SignedBeaconBlock`) including these bids at the beginning of the slot. At the start of the second interval, honest validators submit attestations just as they do previous to this feature). At the start of the third interval, aggregators aggregate these attestations and the builder broadcasts either a full payload or a message indicating that they are withholding the payload (a `SignedExecutionPayloadEnvelope`). At the start of the fourth interval, some validators selected to be members of the new **Payload Timeliness Committee** (PTC) attest to the presence and timeliness of the builder's payload.
|
||||
This feature adds new staked consensus participants called *Builders* and new honest validators duties called *payload timeliness attestations*. The slot is divided in **four** intervals. Honest validators gather *signed bids* (a `SignedExecutionPayloadHeader`) from builders and submit their consensus blocks (a `SignedBeaconBlock`) including these bids at the beginning of the slot. At the start of the second interval, honest validators submit attestations just as they do previous to this feature). At the start of the third interval, aggregators aggregate these attestations and the builder broadcasts either a full payload or a message indicating that they are withholding the payload (a `SignedExecutionPayloadEnvelope`). At the start of the fourth interval, some validators selected to be members of the new **Payload Timeliness Committee** (PTC) attest to the presence and timeliness of the builder's payload.
|
||||
|
||||
At any given slot, the status of the blockchain's head may be either
|
||||
|
||||
@@ -81,33 +76,33 @@ At any given slot, the status of the blockchain's head may be either
|
||||
|
||||
### Payload status
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `PAYLOAD_ABSENT` | `uint8(0)` |
|
||||
| `PAYLOAD_PRESENT` | `uint8(1)` |
|
||||
| `PAYLOAD_WITHHELD` | `uint8(2)` |
|
||||
| Name | Value |
|
||||
| ------------------------ | ---------- |
|
||||
| `PAYLOAD_ABSENT` | `uint8(0)` |
|
||||
| `PAYLOAD_PRESENT` | `uint8(1)` |
|
||||
| `PAYLOAD_WITHHELD` | `uint8(2)` |
|
||||
| `PAYLOAD_INVALID_STATUS` | `uint8(3)` |
|
||||
|
||||
## Preset
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `PTC_SIZE` | `uint64(2**9)` (=512) # (New in EIP-7732) |
|
||||
| Name | Value |
|
||||
| ---------- | ----------------------------------------- |
|
||||
| `PTC_SIZE` | `uint64(2**9)` (=512) # (New in EIP-7732) |
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `DOMAIN_BEACON_BUILDER` | `DomainType('0x1B000000')` # (New in EIP-7732)|
|
||||
| `DOMAIN_PTC_ATTESTER` | `DomainType('0x0C000000')` # (New in EIP-7732)|
|
||||
| Name | Value |
|
||||
| ----------------------- | ---------------------------------------------- |
|
||||
| `DOMAIN_BEACON_BUILDER` | `DomainType('0x1B000000')` # (New in EIP-7732) |
|
||||
| `DOMAIN_PTC_ATTESTER` | `DomainType('0x0C000000')` # (New in EIP-7732) |
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_PAYLOAD_ATTESTATIONS` | `2**2` (= 4) # (New in EIP-7732) |
|
||||
| Name | Value |
|
||||
| -------------------------- | -------------------------------- |
|
||||
| `MAX_PAYLOAD_ATTESTATIONS` | `2**2` (= 4) # (New in EIP-7732) |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -618,6 +613,7 @@ def is_merge_transition_complete(state: BeaconState) -> bool:
|
||||
```
|
||||
|
||||
#### Modified `validate_merge_block`
|
||||
|
||||
`validate_merge_block` is modified to use the new `signed_execution_payload_header` message in the Beacon Block Body
|
||||
|
||||
```python
|
||||
@@ -743,4 +739,5 @@ def is_merge_transition_complete(state: BeaconState) -> bool:
|
||||
kzgs = List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]()
|
||||
header.blob_kzg_commitments_root = kzgs.hash_tree_root()
|
||||
|
||||
return state.latest_execution_payload_header != header
|
||||
return state.latest_execution_payload_header != header
|
||||
```
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Builders attributions](#builders-attributions)
|
||||
@@ -15,8 +11,7 @@
|
||||
- [Constructing the execution payload envelope](#constructing-the-execution-payload-envelope)
|
||||
- [Honest payload withheld messages](#honest-payload-withheld-messages)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -40,9 +35,9 @@ Builders can broadcast a payload bid for the current or the next slot's proposer
|
||||
4. Set `header.block_hash` to be the block hash of the constructed payload, that is `payload.block_hash`.
|
||||
5. Set `header.gas_limit` to be the gas limit of the constructed payload, that is `payload.gas_limit`.
|
||||
6. Set `header.builder_index` to be the validator index of the builder performing these actions.
|
||||
7. Set `header.slot` to be the slot for which this bid is aimed. This slot **MUST** be either the current slot or the next slot.
|
||||
7. Set `header.slot` to be the slot for which this bid is aimed. This slot **MUST** be either the current slot or the next slot.
|
||||
8. Set `header.value` to be the value that the builder will pay the proposer if the bid is accepted. The builder **MUST** have balance enough to fulfill this bid.
|
||||
9. Set `header.kzg_commitments_root` to be the `hash_tree_root` of the `blobsbundle.commitments` field returned by `engine_getPayloadV4`.
|
||||
9. Set `header.kzg_commitments_root` to be the `hash_tree_root` of the `blobsbundle.commitments` field returned by `engine_getPayloadV4`.
|
||||
|
||||
After building the `header`, the builder obtains a `signature` of the header by using
|
||||
|
||||
@@ -106,7 +101,7 @@ def get_blob_sidecars(signed_block: SignedBeaconBlock,
|
||||
|
||||
### Constructing the execution payload envelope
|
||||
|
||||
When the proposer publishes a valid `SignedBeaconBlock` containing a signed commitment by the builder, the builder is later expected to broadcast the corresponding `SignedExecutionPayloadEnvelope` that fulfills this commitment. See below for a special case of an *honestly withheld payload*.
|
||||
When the proposer publishes a valid `SignedBeaconBlock` containing a signed commitment by the builder, the builder is later expected to broadcast the corresponding `SignedExecutionPayloadEnvelope` that fulfills this commitment. See below for a special case of an *honestly withheld payload*.
|
||||
|
||||
To construct the `execution_payload_envelope` the builder must perform the following steps, we alias `header` to be the committed `ExecutionPayloadHeader` in the beacon block.
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -37,8 +33,7 @@
|
||||
- [`on_payload_attestation_message`](#on_payload_attestation_message)
|
||||
- [Modified `validate_merge_block`](#modified-validate_merge_block)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -46,13 +41,13 @@ This is the modification of the fork choice accompanying the EIP-7732 upgrade.
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value |
|
||||
| -------------------- | ----------- |
|
||||
| `PAYLOAD_TIMELY_THRESHOLD` | `PTC_SIZE // 2` (= 256) |
|
||||
| `INTERVALS_PER_SLOT` | `4` # [modified in EIP-7732] |
|
||||
| `PROPOSER_SCORE_BOOST` | `20` # [modified in EIP-7732] |
|
||||
| `PAYLOAD_WITHHOLD_BOOST` | `40` |
|
||||
| `PAYLOAD_REVEAL_BOOST` | `40` |
|
||||
| Name | Value |
|
||||
| -------------------------- | ----------------------------- |
|
||||
| `PAYLOAD_TIMELY_THRESHOLD` | `PTC_SIZE // 2` (= 256) |
|
||||
| `INTERVALS_PER_SLOT` | `4` # [modified in EIP-7732] |
|
||||
| `PROPOSER_SCORE_BOOST` | `20` # [modified in EIP-7732] |
|
||||
| `PAYLOAD_WITHHOLD_BOOST` | `40` |
|
||||
| `PAYLOAD_REVEAL_BOOST` | `40` |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -605,3 +600,4 @@ def validate_merge_block(block: BeaconBlock) -> None:
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -17,8 +13,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -28,9 +23,9 @@ This document describes the process of the EIP-7732 upgrade.
|
||||
|
||||
Warning: this configuration is not definitive.
|
||||
|
||||
| Name | Value |
|
||||
|---------------------| - |
|
||||
| `EIP7732_FORK_VERSION` | `Version('0x09000000')` |
|
||||
| Name | Value |
|
||||
| ---------------------- | ------------------------------------- |
|
||||
| `EIP7732_FORK_VERSION` | `Version('0x09000000')` |
|
||||
| `EIP7732_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
|
||||
## Helper functions
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modification in EIP-7732](#modification-in-eip-7732)
|
||||
@@ -31,8 +27,7 @@
|
||||
- [ExecutionPayloadEnvelopesByRange v1](#executionpayloadenvelopesbyrange-v1)
|
||||
- [ExecutionPayloadEnvelopesByRoot v1](#executionpayloadenvelopesbyroot-v1)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -47,7 +42,7 @@ The specification of these changes continues in the same format as the network s
|
||||
*[Modified in EIP-7732]*
|
||||
|
||||
| Name | Value | Description |
|
||||
|------------------------------------------------|--------------|-------------------------------------------------------------|
|
||||
| ---------------------------------------------- | ------------ | ----------------------------------------------------------- |
|
||||
| `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH_EIP7732` | `13` **TBD** | Merkle proof depth for the `blob_kzg_commitments` list item |
|
||||
|
||||
### Configuration
|
||||
@@ -55,7 +50,7 @@ The specification of these changes continues in the same format as the network s
|
||||
*[New in EIP7732]*
|
||||
|
||||
| Name | Value | Description |
|
||||
|------------------------|----------------|-------------------------------------------------------------------|
|
||||
| ---------------------- | -------------- | ----------------------------------------------------------------- |
|
||||
| `MAX_REQUEST_PAYLOADS` | `2**7` (= 128) | Maximum number of execution payload envelopes in a single request |
|
||||
|
||||
### Containers
|
||||
@@ -114,16 +109,16 @@ Topics follow the same specification as in prior upgrades.
|
||||
The `beacon_block` topic is updated to support the modified type
|
||||
|
||||
| Name | Message Type |
|
||||
|----------------|--------------------------------------------|
|
||||
| -------------- | ------------------------------------------ |
|
||||
| `beacon_block` | `SignedBeaconBlock` [modified in EIP-7732] |
|
||||
|
||||
The new topics along with the type of the `data` field of a gossipsub message are given in this table:
|
||||
|
||||
| Name | Message Type |
|
||||
|-------------------------------|------------------------------------------------------|
|
||||
| `execution_payload_header` | `SignedExecutionPayloadHeader` [New in EIP-7732] |
|
||||
| `execution_payload` | `SignedExecutionPayloadEnvelope` [New in EIP-7732] |
|
||||
| `payload_attestation_message` | `PayloadAttestationMessage` [New in EIP-7732] |
|
||||
| Name | Message Type |
|
||||
| ----------------------------- | -------------------------------------------------- |
|
||||
| `execution_payload_header` | `SignedExecutionPayloadHeader` [New in EIP-7732] |
|
||||
| `execution_payload` | `SignedExecutionPayloadEnvelope` [New in EIP-7732] |
|
||||
| `payload_attestation_message` | `PayloadAttestationMessage` [New in EIP-7732] |
|
||||
|
||||
##### Global topics
|
||||
|
||||
@@ -139,17 +134,17 @@ There are no new validations for this topic. However, all validations with regar
|
||||
|
||||
- _[REJECT]_ The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer -- i.e. validate that `len(signed_beacon_block.message.body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK`
|
||||
- _[REJECT]_ The block's execution payload timestamp is correct with respect to the slot
|
||||
-- i.e. `execution_payload.timestamp == compute_timestamp_at_slot(state, block.slot)`.
|
||||
-- i.e. `execution_payload.timestamp == compute_timestamp_at_slot(state, block.slot)`.
|
||||
- If `execution_payload` verification of block's parent by an execution node is *not* complete:
|
||||
- [REJECT] The block's parent (defined by `block.parent_root`) passes all validation (excluding execution node verification of the `block.body.execution_payload`).
|
||||
- [REJECT] The block's parent (defined by `block.parent_root`) passes all validation (excluding execution node verification of the `block.body.execution_payload`).
|
||||
- otherwise:
|
||||
- [IGNORE] The block's parent (defined by `block.parent_root`) passes all validation (including execution node verification of the `block.body.execution_payload`).
|
||||
- [IGNORE] The block's parent (defined by `block.parent_root`) passes all validation (including execution node verification of the `block.body.execution_payload`).
|
||||
- [REJECT] The block's parent (defined by `block.parent_root`) passes validation.
|
||||
|
||||
And instead the following validations are set in place with the alias `header = signed_execution_payload_header.message`:
|
||||
|
||||
- If `execution_payload` verification of block's execution payload parent by an execution node **is complete**:
|
||||
- [REJECT] The block's execution payload parent (defined by `header.parent_block_hash`) passes all validation.
|
||||
- [REJECT] The block's execution payload parent (defined by `header.parent_block_hash`) passes all validation.
|
||||
- [REJECT] The block's parent (defined by `block.parent_root`) passes validation.
|
||||
|
||||
###### `execution_payload`
|
||||
@@ -167,7 +162,7 @@ Let `header` alias `block.body.signed_execution_payload_header.message` (notice
|
||||
- _[REJECT]_ `block` passes validation.
|
||||
- _[REJECT]_ `envelope.builder_index == header.builder_index`
|
||||
- if `envelope.payload_withheld == False` then
|
||||
- _[REJECT]_ `payload.block_hash == header.block_hash`
|
||||
- _[REJECT]_ `payload.block_hash == header.block_hash`
|
||||
- _[REJECT]_ The builder signature, `signed_execution_payload_envelope.signature`, is valid with respect to the builder's public key.
|
||||
|
||||
###### `payload_attestation_message`
|
||||
@@ -193,9 +188,9 @@ The following validations MUST pass before forwarding the `signed_execution_payl
|
||||
- _[IGNORE]_ this is the first signed bid seen with a valid signature from the given builder for this slot.
|
||||
- _[IGNORE]_ this bid is the highest value bid seen for the pair of the corresponding slot and the given parent block hash.
|
||||
- _[REJECT]_ The signed builder bid, `header.builder_index` is a valid, active, and non-slashed builder index in state.
|
||||
- _[IGNORE]_ The signed builder bid value, `header.value`, is less or equal than the builder's balance in state. i.e. `MIN_BUILDER_BALANCE + header.value < state.builder_balances[header.builder_index]`.
|
||||
- _[IGNORE]_ The signed builder bid value, `header.value`, is less or equal than the builder's balance in state. i.e. `MIN_BUILDER_BALANCE + header.value < state.builder_balances[header.builder_index]`.
|
||||
- _[IGNORE]_ `header.parent_block_hash` is the block hash of a known execution payload in fork choice.
|
||||
_ _[IGNORE]_ `header.parent_block_root` is the hash tree root of a known beacon block in fork choice.
|
||||
\_ _[IGNORE]_ `header.parent_block_root` is the hash tree root of a known beacon block in fork choice.
|
||||
- _[IGNORE]_ `header.slot` is the current slot or the next slot.
|
||||
- _[REJECT]_ The builder signature, `signed_execution_payload_header_envelope.signature`, is valid with respect to the `header_envelope.builder_index`.
|
||||
|
||||
@@ -207,10 +202,10 @@ _ _[IGNORE]_ `header.parent_block_root` is the hash tree root of a known beacon
|
||||
|
||||
**Protocol ID:** `/eth2/beacon_chain/req/beacon_blocks_by_range/2/`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
@@ -224,10 +219,10 @@ _ _[IGNORE]_ `header.parent_block_root` is the hash tree root of a known beacon
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
@@ -239,12 +234,12 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
**Protocol ID:** `/eth2/beacon_chain/req/blob_sidecars_by_root/1/`
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| `DENEB_FORK_VERSION` | `deneb.BlobSidecar` |
|
||||
| `EIP7732_FORK_VERSION` | `eip7732.BlobSidecar` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ---------------------- | --------------------- |
|
||||
| `DENEB_FORK_VERSION` | `deneb.BlobSidecar` |
|
||||
| `EIP7732_FORK_VERSION` | `eip7732.BlobSidecar` |
|
||||
|
||||
##### ExecutionPayloadEnvelopesByRange v1
|
||||
|
||||
@@ -269,16 +264,16 @@ Response Content:
|
||||
)
|
||||
```
|
||||
|
||||
Specifications of req\response methods are equivalent to [BeaconBlocksByRange v2](#beaconblocksbyrange-v2), with the only difference being the response content type.
|
||||
Specifications of req\\response methods are equivalent to [BeaconBlocksByRange v2](#beaconblocksbyrange-v2), with the only difference being the response content type.
|
||||
|
||||
For each `response_chunk`, a `ForkDigest`-context based on `compute_fork_version(compute_epoch_at_slot(signed_execution_payload_envelop.message.slot))` is used to select the fork namespace of the Response type.
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|------------------------|------------------------------------------|
|
||||
| ---------------------- | ---------------------------------------- |
|
||||
| `EIP7732_FORK_VERSION` | `eip7732.SignedExecutionPayloadEnvelope` |
|
||||
|
||||
##### ExecutionPayloadEnvelopesByRoot v1
|
||||
@@ -287,10 +282,10 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
The `<context-bytes>` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|------------------------|------------------------------------------|
|
||||
| ---------------------- | ---------------------------------------- |
|
||||
| `EIP7732_FORK_VERSION` | `eip7732.SignedExecutionPayloadEnvelope` |
|
||||
|
||||
Request Content:
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Validator assignment](#validator-assignment)
|
||||
@@ -15,14 +11,13 @@
|
||||
- [Attestation](#attestation)
|
||||
- [Sync Committee participations](#sync-committee-participations)
|
||||
- [Block proposal](#block-proposal)
|
||||
- [Constructing the new `signed_execution_payload_header` field in `BeaconBlockBody`](#constructing-the-new-signed_execution_payload_header-field-in--beaconblockbody)
|
||||
- [Constructing the new `payload_attestations` field in `BeaconBlockBody`](#constructing-the-new-payload_attestations-field-in--beaconblockbody)
|
||||
- [Constructing the new `signed_execution_payload_header` field in `BeaconBlockBody`](#constructing-the-new-signed_execution_payload_header-field-in-beaconblockbody)
|
||||
- [Constructing the new `payload_attestations` field in `BeaconBlockBody`](#constructing-the-new-payload_attestations-field-in-beaconblockbody)
|
||||
- [Blob sidecars](#blob-sidecars)
|
||||
- [Payload timeliness attestation](#payload-timeliness-attestation)
|
||||
- [Constructing a payload attestation](#constructing-a-payload-attestation)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -30,7 +25,7 @@ This document represents the changes and additions to the Honest validator guide
|
||||
|
||||
## Validator assignment
|
||||
|
||||
A validator may be a member of the new Payload Timeliness Committee (PTC) for a given slot. To check for PTC assignments the validator uses the helper `get_ptc_assignment(state, epoch, validator_index)` where `epoch <= next_epoch`.
|
||||
A validator may be a member of the new Payload Timeliness Committee (PTC) for a given slot. To check for PTC assignments the validator uses the helper `get_ptc_assignment(state, epoch, validator_index)` where `epoch <= next_epoch`.
|
||||
|
||||
PTC committee selection is only stable within the context of the current and next epoch.
|
||||
|
||||
@@ -78,32 +73,33 @@ Sync committee duties are not changed for validators, however the submission dea
|
||||
|
||||
Validators are still expected to propose `SignedBeaconBlock` at the beginning of any slot during which `is_proposer(state, validator_index)` returns `true`. The mechanism to prepare this beacon block and related sidecars differs from previous forks as follows
|
||||
|
||||
#### Constructing the new `signed_execution_payload_header` field in `BeaconBlockBody`
|
||||
#### Constructing the new `signed_execution_payload_header` field in `BeaconBlockBody`
|
||||
|
||||
To obtain `signed_execution_payload_header`, a block proposer building a block on top of a `state` must take the following actions:
|
||||
|
||||
* Listen to the `execution_payload_header` gossip global topic and save an accepted `signed_execution_payload_header` from a builder. Proposer MAY obtain these signed messages by other off-protocol means.
|
||||
* The `signed_execution_payload_header` must satisfy the verification conditions found in `process_execution_payload_header`, that is
|
||||
- The header signature must be valid
|
||||
- The builder balance can cover the header value
|
||||
- The header slot is for the proposal block slot
|
||||
- The header parent block hash equals the state's `latest_block_hash`.
|
||||
- The header parent block root equals the current block's `parent_root`.
|
||||
* Select one bid and set `body.signed_execution_payload_header = signed_execution_payload_header`
|
||||
- Listen to the `execution_payload_header` gossip global topic and save an accepted `signed_execution_payload_header` from a builder. Proposer MAY obtain these signed messages by other off-protocol means.
|
||||
- The `signed_execution_payload_header` must satisfy the verification conditions found in `process_execution_payload_header`, that is
|
||||
- The header signature must be valid
|
||||
- The builder balance can cover the header value
|
||||
- The header slot is for the proposal block slot
|
||||
- The header parent block hash equals the state's `latest_block_hash`.
|
||||
- The header parent block root equals the current block's `parent_root`.
|
||||
- Select one bid and set `body.signed_execution_payload_header = signed_execution_payload_header`
|
||||
|
||||
#### Constructing the new `payload_attestations` field in `BeaconBlockBody`
|
||||
#### Constructing the new `payload_attestations` field in `BeaconBlockBody`
|
||||
|
||||
Up to `MAX_PAYLOAD_ATTESTATIONS`, aggregate payload attestations can be included in the block. The validator will have to
|
||||
|
||||
* Listen to the `payload_attestation_message` gossip global topic
|
||||
* The payload attestations added must satisfy the verification conditions found in payload attestation gossip validation and payload attestation processing. This means
|
||||
- The `data.beacon_block_root` corresponds to `block.parent_root`.
|
||||
- The slot of the parent block is exactly one slot before the proposing slot.
|
||||
- The signature of the payload attestation data message verifies correctly.
|
||||
* The proposer needs to aggregate all payload attestations with the same data into a given `PayloadAttestation` object. For this it needs to fill the `aggregation_bits` field by using the relative position of the validator indices with respect to the PTC that is obtained from `get_ptc(state, block_slot - 1)`.
|
||||
* The proposer should only include payload attestations that are consistent with the current block they are proposing. That is, if the previous block had a payload, they should only include attestations with `payload_status = PAYLOAD_PRESENT`. Proposers are penalized for attestations that are not-consistent with their view.
|
||||
- Listen to the `payload_attestation_message` gossip global topic
|
||||
- The payload attestations added must satisfy the verification conditions found in payload attestation gossip validation and payload attestation processing. This means
|
||||
- The `data.beacon_block_root` corresponds to `block.parent_root`.
|
||||
- The slot of the parent block is exactly one slot before the proposing slot.
|
||||
- The signature of the payload attestation data message verifies correctly.
|
||||
- The proposer needs to aggregate all payload attestations with the same data into a given `PayloadAttestation` object. For this it needs to fill the `aggregation_bits` field by using the relative position of the validator indices with respect to the PTC that is obtained from `get_ptc(state, block_slot - 1)`.
|
||||
- The proposer should only include payload attestations that are consistent with the current block they are proposing. That is, if the previous block had a payload, they should only include attestations with `payload_status = PAYLOAD_PRESENT`. Proposers are penalized for attestations that are not-consistent with their view.
|
||||
|
||||
#### Blob sidecars
|
||||
|
||||
The blob sidecars are no longer broadcast by the validator, and thus their construction is not necessary. This deprecates the corresponding sections from the honest validator guide in the Electra fork, moving them, albeit with some modifications, to the [honest Builder guide](./builder.md)
|
||||
|
||||
### Payload timeliness attestation
|
||||
@@ -115,19 +111,19 @@ A validator should create and broadcast the `payload_attestation_message` to the
|
||||
#### Constructing a payload attestation
|
||||
|
||||
If a validator is in the payload attestation committee for the current slot (as obtained from `get_ptc_assignment` above) then the validator should prepare a `PayloadAttestationMessage` for the current slot,
|
||||
according to the logic in `get_payload_attestation_message` below and broadcast it not after `SECONDS_PER_SLOT * 3 / INTERVALS_PER_SLOT` seconds since the start of the slot, to the global `payload_attestation_message` pubsub topic.
|
||||
according to the logic in `get_payload_attestation_message` below and broadcast it not after `SECONDS_PER_SLOT * 3 / INTERVALS_PER_SLOT` seconds since the start of the slot, to the global `payload_attestation_message` pubsub topic.
|
||||
|
||||
The validator creates `payload_attestation_message` as follows:
|
||||
|
||||
* If the validator has not seen any beacon block for the assigned slot, do not submit a payload attestation. It will be ignored anyway.
|
||||
* Set `data.beacon_block_root` be the HTR of the beacon block seen for the assigned slot
|
||||
* Set `data.slot` to be the assigned slot.
|
||||
* Set `data.payload_status` as follows
|
||||
- If a `SignedExecutionPayloadEnvelope` has been seen referencing the block `data.beacon_block_root` and the envelope has `payload_withheld = False`, set to `PAYLOAD_PRESENT`.
|
||||
- If a `SignedExecutionPayloadEnvelope` has been seen referencing the block `data.beacon_block_root` and the envelope has `payload_withheld = True`, set to `PAYLOAD_WITHHELD`.
|
||||
- If no `SignedExecutionPayloadEnvelope` has been seen referencing the block `data.beacon_block_root` set to `PAYLOAD_ABSENT`.
|
||||
* Set `payload_attestation_message.validator_index = validator_index` where `validator_index` is the validator chosen to submit. The private key mapping to `state.validators[validator_index].pubkey` is used to sign the payload timeliness attestation.
|
||||
* Sign the `payload_attestation_message.data` using the helper `get_payload_attestation_message_signature`.
|
||||
- If the validator has not seen any beacon block for the assigned slot, do not submit a payload attestation. It will be ignored anyway.
|
||||
- Set `data.beacon_block_root` be the HTR of the beacon block seen for the assigned slot
|
||||
- Set `data.slot` to be the assigned slot.
|
||||
- Set `data.payload_status` as follows
|
||||
- If a `SignedExecutionPayloadEnvelope` has been seen referencing the block `data.beacon_block_root` and the envelope has `payload_withheld = False`, set to `PAYLOAD_PRESENT`.
|
||||
- If a `SignedExecutionPayloadEnvelope` has been seen referencing the block `data.beacon_block_root` and the envelope has `payload_withheld = True`, set to `PAYLOAD_WITHHELD`.
|
||||
- If no `SignedExecutionPayloadEnvelope` has been seen referencing the block `data.beacon_block_root` set to `PAYLOAD_ABSENT`.
|
||||
- Set `payload_attestation_message.validator_index = validator_index` where `validator_index` is the validator chosen to submit. The private key mapping to `state.validators[validator_index].pubkey` is used to sign the payload timeliness attestation.
|
||||
- Sign the `payload_attestation_message.data` using the helper `get_payload_attestation_message_signature`.
|
||||
|
||||
Notice that the attester only signs the `PayloadAttestationData` and not the `validator_index` field in the message. Proposers need to aggregate these attestations as described above.
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# EIP-7805 -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Preset](#preset)
|
||||
@@ -29,34 +25,34 @@
|
||||
- [Modified `verify_and_notify_new_payload`](#modified-verify_and_notify_new_payload)
|
||||
- [Modified `process_execution_payload`](#modified-process_execution_payload)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
This is the beacon chain specification to add EIP-7805 / fork-choice enforced, committee-based inclusion list (FOCIL) mechanism to allow forced transaction inclusion. Refers to the following posts:
|
||||
|
||||
- [Fork-Choice enforced Inclusion Lists (FOCIL): A simple committee-based inclusion list proposal](https://ethresear.ch/t/fork-choice-enforced-inclusion-lists-focil-a-simple-committee-based-inclusion-list-proposal/19870/1)
|
||||
- [FOCIL CL & EL workflow](https://ethresear.ch/t/focil-cl-el-workflow/20526)
|
||||
*Note*: This specification is built upon [Electra](../../electra/beacon_chain.md) and is under active development.
|
||||
*Note*: This specification is built upon [Electra](../../electra/beacon_chain.md) and is under active development.
|
||||
|
||||
## Preset
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| --------------------------------- | -------------------------- |
|
||||
| `DOMAIN_INCLUSION_LIST_COMMITTEE` | `DomainType('0x0C000000')` |
|
||||
|
||||
### Inclusion List Committee
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ------------------------------- | -------------------- |
|
||||
| `INCLUSION_LIST_COMMITTEE_SIZE` | `uint64(2**4)` (=16) |
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ------------------------------------- | ------------------- |
|
||||
| `MAX_TRANSACTIONS_PER_INCLUSION_LIST` | `uint64(1)` **TBD** |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
# EIP-7805 -- Fork Choice
|
||||
|
||||
## Table of contents
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -16,8 +13,7 @@
|
||||
- [Modified `get_proposer_head`](#modified-get_proposer_head)
|
||||
- [New `on_inclusion_list`](#new-on_inclusion_list)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -27,8 +23,8 @@ This is the modification of the fork choice accompanying the EIP-7805 upgrade.
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ---------------------- | ------------------------------- | :-----: | :-------: |
|
||||
| `VIEW_FREEZE_DEADLINE` | `SECONDS_PER_SLOT * 2 // 3 + 1` | seconds | 9 seconds |
|
||||
|
||||
## Fork choice
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -16,8 +12,7 @@
|
||||
- [Fork to EIP-7805](#fork-to-eip-7805)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -27,10 +22,10 @@ This document describes the process of the EIP-7805 upgrade.
|
||||
|
||||
Warning: this configuration is not definitive.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `EIP7805_FORK_VERSION` | `Version('0x10000000')` |
|
||||
| `EIP7805_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
| Name | Value |
|
||||
| ---------------------- | ------------------------------------- |
|
||||
| `EIP7805_FORK_VERSION` | `Version('0x10000000')` |
|
||||
| `EIP7805_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This document contains the consensus-layer networking specification for EIP-7805.
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Modifications in EIP-7805](#modifications-in-eip-7805)
|
||||
- [Configuration](#configuration)
|
||||
@@ -15,19 +14,19 @@ This document contains the consensus-layer networking specification for EIP-7805
|
||||
- [Messages](#messages)
|
||||
- [InclusionListByCommitteeIndices v1](#inclusionlistbycommitteeindices-v1)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Modifications in EIP-7805
|
||||
|
||||
### Configuration
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ---------------------- | ----------------------- | :-----: | :-------: |
|
||||
| `ATTESTATION_DEADLINE` | `SECONDS_PER_SLOT // 3` | seconds | 4 seconds |
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MAX_REQUEST_INCLUSION_LIST` | `2**4` (= 16) | Maximum number of inclusion list in a single request |
|
||||
| Name | Value | Description |
|
||||
| ------------------------------ | ---------------- | ---------------------------------------------------------- |
|
||||
| `MAX_REQUEST_INCLUSION_LIST` | `2**4` (= 16) | Maximum number of inclusion list in a single request |
|
||||
| `MAX_BYTES_PER_INCLUSION_LIST` | `2**13` (= 8192) | Maximum size of the inclusion list's transactions in bytes |
|
||||
|
||||
### The gossip domain: gossipsub
|
||||
@@ -36,8 +35,8 @@ This document contains the consensus-layer networking specification for EIP-7805
|
||||
|
||||
The new topics along with the type of the `data` field of a gossipsub message are given in this table:
|
||||
|
||||
| Name | Message Type |
|
||||
| - | - |
|
||||
| Name | Message Type |
|
||||
| ---------------- | --------------------- |
|
||||
| `inclusion_list` | `SignedInclusionList` |
|
||||
|
||||
##### Global topics
|
||||
@@ -68,10 +67,10 @@ The following validations MUST pass before forwarding the `inclusion_list` on th
|
||||
|
||||
The `<context-bytes>` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|------------------------|--------------------------------|
|
||||
| ---------------------- | ------------------------------ |
|
||||
| `EIP7805_FORK_VERSION` | `EIP-7805.SignedInclusionList` |
|
||||
|
||||
Request Content:
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# EIP-7805 -- Honest Validator
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -18,14 +14,13 @@
|
||||
- [Block proposal](#block-proposal)
|
||||
- [Update execution client with inclusion lists](#update-execution-client-with-inclusion-lists)
|
||||
- [New inclusion list committee duty](#new-inclusion-list-committee-duty)
|
||||
- [Constructing a signed inclusion list](#constructing-a-signed-inclusion-list)
|
||||
- [Constructing a signed inclusion list](#constructing-a-signed-inclusion-list)
|
||||
- [Modified attester duty](#modified-attester-duty)
|
||||
- [Modified LMD GHOST vote](#modified-lmd-ghost-vote)
|
||||
- [Modified LMD GHOST vote](#modified-lmd-ghost-vote)
|
||||
- [Modified sync committee duty](#modified-sync-committee-duty)
|
||||
- [Modified beacon block root](#modified-beacon-block-root)
|
||||
- [Modified beacon block root](#modified-beacon-block-root)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -43,8 +38,8 @@ Please see related Beacon Chain doc before continuing and use them as a referenc
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit | Duration |
|
||||
| --------------------------------- | ---------------------- | :-----: | :--------: |
|
||||
| `PROPOSER_INCLUSION_LIST_CUT_OFF` | `SECONDS_PER_SLOT - 1` | seconds | 11 seconds |
|
||||
|
||||
## Protocol
|
||||
@@ -103,6 +98,7 @@ A validator should create and broadcast the `signed_inclusion_list` to the globa
|
||||
#### Constructing a signed inclusion list
|
||||
|
||||
The validator creates the `signed_inclusion_list` as follows:
|
||||
|
||||
- First, the validator creates the `inclusion_list`.
|
||||
- Set `inclusion_list.slot` to the assigned slot returned by `get_inclusion_committee_assignment`.
|
||||
- Set `inclusion_list.validator_index` to the validator's index.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -55,58 +51,57 @@
|
||||
- [Participation flags updates](#participation-flags-updates)
|
||||
- [Sync committee updates](#sync-committee-updates)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
Altair is the first beacon chain hard fork. Its main features are:
|
||||
|
||||
* sync committees to support light clients
|
||||
* incentive accounting reforms to reduce spec complexity
|
||||
* penalty parameter updates towards their planned maximally punitive values
|
||||
- sync committees to support light clients
|
||||
- incentive accounting reforms to reduce spec complexity
|
||||
- penalty parameter updates towards their planned maximally punitive values
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `ParticipationFlags` | `uint8` | a succinct representation of 8 boolean participation flags |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| -------------------- | -------------- | ---------------------------------------------------------- |
|
||||
| `ParticipationFlags` | `uint8` | a succinct representation of 8 boolean participation flags |
|
||||
|
||||
## Constants
|
||||
|
||||
### Participation flag indices
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `TIMELY_SOURCE_FLAG_INDEX` | `0` |
|
||||
| `TIMELY_TARGET_FLAG_INDEX` | `1` |
|
||||
| `TIMELY_HEAD_FLAG_INDEX` | `2` |
|
||||
| Name | Value |
|
||||
| -------------------------- | ----- |
|
||||
| `TIMELY_SOURCE_FLAG_INDEX` | `0` |
|
||||
| `TIMELY_TARGET_FLAG_INDEX` | `1` |
|
||||
| `TIMELY_HEAD_FLAG_INDEX` | `2` |
|
||||
|
||||
### Incentivization weights
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ---------------------- | ------------ |
|
||||
| `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)` |
|
||||
| `TIMELY_HEAD_WEIGHT` | `uint64(14)` |
|
||||
| `SYNC_REWARD_WEIGHT` | `uint64(2)` |
|
||||
| `PROPOSER_WEIGHT` | `uint64(8)` |
|
||||
| `WEIGHT_DENOMINATOR` | `uint64(64)` |
|
||||
|
||||
*Note*: The sum of the weights equal `WEIGHT_DENOMINATOR`.
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `DOMAIN_SYNC_COMMITTEE` | `DomainType('0x07000000')` |
|
||||
| Name | Value |
|
||||
| --------------------------------------- | -------------------------- |
|
||||
| `DOMAIN_SYNC_COMMITTEE` | `DomainType('0x07000000')` |
|
||||
| `DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF` | `DomainType('0x08000000')` |
|
||||
| `DOMAIN_CONTRIBUTION_AND_PROOF` | `DomainType('0x09000000')` |
|
||||
| `DOMAIN_CONTRIBUTION_AND_PROOF` | `DomainType('0x09000000')` |
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ---------------------------- | ------------------------------------------------------------------ |
|
||||
| `PARTICIPATION_FLAG_WEIGHTS` | `[TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, TIMELY_HEAD_WEIGHT]` |
|
||||
|
||||
## Preset
|
||||
@@ -117,26 +112,26 @@ This patch updates a few configuration values to move penalty parameters closer
|
||||
|
||||
*Note*: The spec does *not* override previous configuration values but instead creates new values and replaces usage throughout.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `INACTIVITY_PENALTY_QUOTIENT_ALTAIR` | `uint64(3 * 2**24)` (= 50,331,648) |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR` | `uint64(2**6)` (= 64) |
|
||||
| `PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR` | `uint64(2)` |
|
||||
| Name | Value |
|
||||
| ----------------------------------------- | ---------------------------------- |
|
||||
| `INACTIVITY_PENALTY_QUOTIENT_ALTAIR` | `uint64(3 * 2**24)` (= 50,331,648) |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR` | `uint64(2**6)` (= 64) |
|
||||
| `PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR` | `uint64(2)` |
|
||||
|
||||
### Sync committee
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | - | - |
|
||||
| `SYNC_COMMITTEE_SIZE` | `uint64(2**9)` (= 512) | validators | |
|
||||
| `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` | `uint64(2**8)` (= 256) | epochs | ~27 hours |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ---------------------------------- | ---------------------- | ---------- | --------- |
|
||||
| `SYNC_COMMITTEE_SIZE` | `uint64(2**9)` (= 512) | validators | |
|
||||
| `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` | `uint64(2**8)` (= 256) | epochs | ~27 hours |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Inactivity penalties
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `INACTIVITY_SCORE_BIAS` | `uint64(2**2)` (= 4) | score points per inactive epoch |
|
||||
| Name | Value | Description |
|
||||
| -------------------------------- | --------------------- | -------------------------------- |
|
||||
| `INACTIVITY_SCORE_BIAS` | `uint64(2**2)` (= 4) | score points per inactive epoch |
|
||||
| `INACTIVITY_SCORE_RECOVERY_RATE` | `uint64(2**4)` (= 16) | score points per leak-free epoch |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair -- BLS extensions
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -12,8 +8,7 @@
|
||||
- [`eth_aggregate_pubkeys`](#eth_aggregate_pubkeys)
|
||||
- [`eth_fast_aggregate_verify`](#eth_fast_aggregate_verify)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -23,8 +18,8 @@ Knowledge of the [phase 0 specification](../phase0/beacon-chain.md) is assumed,
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ---------------------- | -------------------------------------- |
|
||||
| `G2_POINT_AT_INFINITY` | `BLSSignature(b'\xc0' + b'\x00' * 95)` |
|
||||
|
||||
## Extensions
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair -- Fork Logic
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -15,8 +11,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -24,10 +19,10 @@ This document describes the process of the first upgrade of the beacon chain: th
|
||||
|
||||
## Configuration
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `ALTAIR_FORK_VERSION` | `Version('0x01000000')` |
|
||||
| `ALTAIR_FORK_EPOCH` | `Epoch(74240)` (Oct 27, 2021, 10:56:23am UTC) |
|
||||
| Name | Value |
|
||||
| --------------------- | --------------------------------------------- |
|
||||
| `ALTAIR_FORK_VERSION` | `Version('0x01000000')` |
|
||||
| `ALTAIR_FORK_EPOCH` | `Epoch(74240)` (Oct 27, 2021, 10:56:23am UTC) |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair Light Client -- Full Node
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
@@ -16,8 +12,7 @@
|
||||
- [`create_light_client_finality_update`](#create_light_client_finality_update)
|
||||
- [`create_light_client_optimistic_update`](#create_light_client_optimistic_update)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -57,6 +52,7 @@ Full nodes are expected to derive light client data from historic blocks and sta
|
||||
### `create_light_client_bootstrap`
|
||||
|
||||
To form a `LightClientBootstrap`, the following objects are needed:
|
||||
|
||||
- `state`: the post state of any post-Altair block
|
||||
- `block`: the corresponding block
|
||||
|
||||
@@ -87,6 +83,7 @@ Blocks are considered to be epoch boundary blocks if their block root can occur
|
||||
### `create_light_client_update`
|
||||
|
||||
To form a `LightClientUpdate`, the following historical states and blocks are needed:
|
||||
|
||||
- `state`: the post state of any block with a post-Altair parent block
|
||||
- `block`: the corresponding block
|
||||
- `attested_state`: the post state of `attested_block`
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
# Altair Light Client -- Light Client
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Light client sync process](#light-client-sync-process)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair Light Client -- Networking
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Networking](#networking)
|
||||
- [Configuration](#configuration)
|
||||
@@ -24,8 +20,7 @@
|
||||
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
|
||||
- [Sync committee](#sync-committee)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Networking
|
||||
|
||||
@@ -33,8 +28,8 @@ This section extends the [networking specification for Altair](../p2p-interface.
|
||||
|
||||
### Configuration
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| ---------------------------------- | -------------- | ------------------------------------------------------------------- |
|
||||
| `MAX_REQUEST_LIGHT_CLIENT_UPDATES` | `2**7` (= 128) | Maximum number of `LightClientUpdate` instances in a single request |
|
||||
|
||||
### The gossip domain: gossipsub
|
||||
@@ -45,9 +40,9 @@ Gossip meshes are added to allow light clients to stay in sync with the network.
|
||||
|
||||
New global topics are added to provide light clients with the latest updates.
|
||||
|
||||
| name | Message Type |
|
||||
| - | - |
|
||||
| `light_client_finality_update` | `LightClientFinalityUpdate` |
|
||||
| name | Message Type |
|
||||
| -------------------------------- | ----------------------------- |
|
||||
| `light_client_finality_update` | `LightClientFinalityUpdate` |
|
||||
| `light_client_optimistic_update` | `LightClientOptimisticUpdate` |
|
||||
|
||||
##### Global topics
|
||||
@@ -76,12 +71,12 @@ The gossip `ForkDigestValue` is determined based on `compute_fork_version(comput
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
| ------------------------------- | ------------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientFinalityUpdate` |
|
||||
| `fork_version` | Message SSZ type |
|
||||
| ------------------------------- | ---------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientFinalityUpdate` |
|
||||
|
||||
###### `light_client_optimistic_update`
|
||||
|
||||
@@ -107,7 +102,7 @@ The gossip `ForkDigestValue` is determined based on `compute_fork_version(comput
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
| ------------------------------- | ------------------------------------ |
|
||||
@@ -150,12 +145,12 @@ A `ForkDigest`-context based on `compute_fork_version(compute_epoch_at_slot(boot
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------- | ------------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientBootstrap` |
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------- | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientBootstrap` |
|
||||
|
||||
##### LightClientUpdatesByRange
|
||||
|
||||
@@ -190,12 +185,12 @@ For each `response_chunk`, a `ForkDigest`-context based on `compute_fork_version
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
| ------------------------------- | ------------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientUpdate` |
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
| ------------------------------- | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientUpdate` |
|
||||
|
||||
##### GetLightClientFinalityUpdate
|
||||
|
||||
@@ -221,12 +216,12 @@ A `ForkDigest`-context based on `compute_fork_version(compute_epoch_at_slot(fina
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------- | ------------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientFinalityUpdate` |
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------- | ---------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` and later | `altair.LightClientFinalityUpdate` |
|
||||
|
||||
##### GetLightClientOptimisticUpdate
|
||||
|
||||
@@ -252,7 +247,7 @@ A `ForkDigest`-context based on `compute_fork_version(compute_epoch_at_slot(opti
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------- | ------------------------------------ |
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair Light Client -- Sync Protocol
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -41,8 +37,7 @@
|
||||
- [`process_light_client_finality_update`](#process_light_client_finality_update)
|
||||
- [`process_light_client_optimistic_update`](#process_light_client_optimistic_update)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -55,34 +50,35 @@ This document suggests a minimal light client design for the beacon chain that
|
||||
uses sync committees introduced in [this beacon chain extension](../beacon-chain.md).
|
||||
|
||||
Additional documents describe how the light client sync protocol can be used:
|
||||
|
||||
- [Full node](./full-node.md)
|
||||
- [Light client](./light-client.md)
|
||||
- [Networking](./p2p-interface.md)
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `FinalityBranch` | `Vector[Bytes32, floorlog2(FINALIZED_ROOT_GINDEX)]` | Merkle branch of `finalized_checkpoint.root` within `BeaconState` |
|
||||
| `CurrentSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(CURRENT_SYNC_COMMITTEE_GINDEX)]` | Merkle branch of `current_sync_committee` within `BeaconState` |
|
||||
| `NextSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(NEXT_SYNC_COMMITTEE_GINDEX)]` | Merkle branch of `next_sync_committee` within `BeaconState` |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ---------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `FinalityBranch` | `Vector[Bytes32, floorlog2(FINALIZED_ROOT_GINDEX)]` | Merkle branch of `finalized_checkpoint.root` within `BeaconState` |
|
||||
| `CurrentSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(CURRENT_SYNC_COMMITTEE_GINDEX)]` | Merkle branch of `current_sync_committee` within `BeaconState` |
|
||||
| `NextSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(NEXT_SYNC_COMMITTEE_GINDEX)]` | Merkle branch of `next_sync_committee` within `BeaconState` |
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `FINALIZED_ROOT_GINDEX` | `get_generalized_index(BeaconState, 'finalized_checkpoint', 'root')` (= 105) |
|
||||
| `CURRENT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(BeaconState, 'current_sync_committee')` (= 54) |
|
||||
| `NEXT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(BeaconState, 'next_sync_committee')` (= 55) |
|
||||
| Name | Value |
|
||||
| ------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `FINALIZED_ROOT_GINDEX` | `get_generalized_index(BeaconState, 'finalized_checkpoint', 'root')` (= 105) |
|
||||
| `CURRENT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(BeaconState, 'current_sync_committee')` (= 54) |
|
||||
| `NEXT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(BeaconState, 'next_sync_committee')` (= 55) |
|
||||
|
||||
## Preset
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | - | - |
|
||||
| `MIN_SYNC_COMMITTEE_PARTICIPANTS` | `1` | validators | |
|
||||
| `UPDATE_TIMEOUT` | `SLOTS_PER_EPOCH * EPOCHS_PER_SYNC_COMMITTEE_PERIOD` | slots | ~27.3 hours |
|
||||
| Name | Value | Unit | Duration |
|
||||
| --------------------------------- | ---------------------------------------------------- | ---------- | ----------- |
|
||||
| `MIN_SYNC_COMMITTEE_PARTICIPANTS` | `1` | validators | |
|
||||
| `UPDATE_TIMEOUT` | `SLOTS_PER_EPOCH * EPOCHS_PER_SYNC_COMMITTEE_PERIOD` | slots | ~27.3 hours |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -357,9 +353,9 @@ def initialize_light_client_store(trusted_block_root: Root,
|
||||
## Light client state updates
|
||||
|
||||
- A light client receives objects of type `LightClientUpdate`, `LightClientFinalityUpdate` and `LightClientOptimisticUpdate`:
|
||||
- **`update: LightClientUpdate`**: Every `update` triggers `process_light_client_update(store, update, current_slot, genesis_validators_root)` where `current_slot` is the current slot based on a local clock.
|
||||
- **`finality_update: LightClientFinalityUpdate`**: Every `finality_update` triggers `process_light_client_finality_update(store, finality_update, current_slot, genesis_validators_root)`.
|
||||
- **`optimistic_update: LightClientOptimisticUpdate`**: Every `optimistic_update` triggers `process_light_client_optimistic_update(store, optimistic_update, current_slot, genesis_validators_root)`.
|
||||
- **`update: LightClientUpdate`**: Every `update` triggers `process_light_client_update(store, update, current_slot, genesis_validators_root)` where `current_slot` is the current slot based on a local clock.
|
||||
- **`finality_update: LightClientFinalityUpdate`**: Every `finality_update` triggers `process_light_client_finality_update(store, finality_update, current_slot, genesis_validators_root)`.
|
||||
- **`optimistic_update: LightClientOptimisticUpdate`**: Every `optimistic_update` triggers `process_light_client_optimistic_update(store, optimistic_update, current_slot, genesis_validators_root)`.
|
||||
- `process_light_client_store_force_update` MAY be called based on use case dependent heuristics if light client sync appears stuck.
|
||||
|
||||
### `validate_light_client_update`
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Altair -- Networking
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Altair](#modifications-in-altair)
|
||||
@@ -30,8 +26,7 @@
|
||||
- [ENR structure](#enr-structure)
|
||||
- [Sync committee bitfield](#sync-committee-bitfield)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -75,11 +70,11 @@ The specification around the creation, validation, and dissemination of messages
|
||||
The derivation of the `message-id` has changed starting with Altair to incorporate the message `topic` along with the message `data`. These are fields of the `Message` Protobuf, and interpreted as empty byte strings if missing.
|
||||
The `message-id` MUST be the following 20 byte value computed from the message:
|
||||
|
||||
* If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
- If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
the concatenation of the following data: `MESSAGE_DOMAIN_VALID_SNAPPY`, the length of the topic byte string (encoded as little-endian `uint64`),
|
||||
the topic byte string, and the snappy decompressed message data:
|
||||
i.e. `SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) + message.topic + snappy_decompress(message.data))[:20]`.
|
||||
* Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
- Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
the concatenation of the following data: `MESSAGE_DOMAIN_INVALID_SNAPPY`, the length of the topic byte string (encoded as little-endian `uint64`),
|
||||
the topic byte string, and the raw message data:
|
||||
i.e. `SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) + message.topic + message.data)[:20]`.
|
||||
@@ -92,11 +87,11 @@ for example, `if topic in phase0_topics: return phase0_msg_id_fn(message) else r
|
||||
|
||||
The new topics along with the type of the `data` field of a gossipsub message are given in this table:
|
||||
|
||||
| Name | Message Type |
|
||||
| - | - |
|
||||
| `beacon_block` | `SignedBeaconBlock` (modified) |
|
||||
| `sync_committee_contribution_and_proof` | `SignedContributionAndProof` |
|
||||
| `sync_committee_{subnet_id}` | `SyncCommitteeMessage` |
|
||||
| Name | Message Type |
|
||||
| --------------------------------------- | ------------------------------ |
|
||||
| `beacon_block` | `SignedBeaconBlock` (modified) |
|
||||
| `sync_committee_contribution_and_proof` | `SignedContributionAndProof` |
|
||||
| `sync_committee_{subnet_id}` | `SyncCommitteeMessage` |
|
||||
|
||||
Definitions of these new types can be found in the [Altair validator guide](./validator.md#containers).
|
||||
|
||||
@@ -229,7 +224,7 @@ Starting with Altair, and in future forks, SSZ type definitions may change.
|
||||
For this common case, we define the `ForkDigest`-context:
|
||||
|
||||
A fixed-width 4 byte `<context-bytes>`, set to the `ForkDigest` matching the chunk:
|
||||
`compute_fork_digest(fork_version, genesis_validators_root)`.
|
||||
`compute_fork_digest(fork_version, genesis_validators_root)`.
|
||||
|
||||
#### Messages
|
||||
|
||||
@@ -241,12 +236,12 @@ Request and Response remain unchanged. A `ForkDigest`-context is used to select
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ---------------------- | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
|
||||
##### BeaconBlocksByRoot v2
|
||||
|
||||
@@ -256,12 +251,12 @@ Request and Response remain unchanged. A `ForkDigest`-context is used to select
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ---------------------- | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
|
||||
##### GetMetaData v2
|
||||
|
||||
@@ -303,8 +298,8 @@ An additional bitfield is added to the ENR under the key `syncnets` to facilitat
|
||||
The length of this bitfield is `SYNC_COMMITTEE_SUBNET_COUNT` where each bit corresponds to a distinct `subnet_id` for a specific sync committee subnet.
|
||||
The `i`th bit is set in this bitfield if the validator is currently subscribed to the `sync_committee_{i}` topic.
|
||||
|
||||
| Key | Value |
|
||||
|:-------------|:-------------------------------------------------|
|
||||
| `syncnets` | SSZ `Bitvector[SYNC_COMMITTEE_SUBNET_COUNT]` |
|
||||
| Key | Value |
|
||||
| :--------- | :------------------------------------------- |
|
||||
| `syncnets` | SSZ `Bitvector[SYNC_COMMITTEE_SUBNET_COUNT]` |
|
||||
|
||||
See the [validator document](./validator.md#sync-committee-subnet-stability) for further details on how the new bits are used.
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
This is an accompanying document to [Altair -- The Beacon Chain](./beacon-chain.md), which describes the expected actions of a "validator" participating in the Ethereum proof-of-stake protocol.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -43,8 +39,7 @@ This is an accompanying document to [Altair -- The Beacon Chain](./beacon-chain.
|
||||
- [Broadcast sync committee contribution](#broadcast-sync-committee-contribution)
|
||||
- [Sync committee subnet stability](#sync-committee-subnet-stability)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -66,10 +61,10 @@ Please see this document before continuing and use as a reference throughout.
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Unit |
|
||||
| - | - | :-: |
|
||||
| `TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE` | `2**4` (= 16) | validators |
|
||||
| `SYNC_COMMITTEE_SUBNET_COUNT` | `4` | The number of sync committee subnets used in the gossipsub aggregation protocol. |
|
||||
| Name | Value | Unit |
|
||||
| ------------------------------------------ | ------------- | :------------------------------------------------------------------------------: |
|
||||
| `TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE` | `2**4` (= 16) | validators |
|
||||
| `SYNC_COMMITTEE_SUBNET_COUNT` | `4` | The number of sync committee subnets used in the gossipsub aggregation protocol. |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -177,9 +172,9 @@ For this reason, *always* get committee assignments via the fields of the `Beaco
|
||||
A validator should plan for future sync committee assignments by noting which sync committee periods they are selected for participation.
|
||||
Specifically, a validator should:
|
||||
|
||||
* Upon (re)syncing the chain and upon sync committee period boundaries, check for assignments in the current and next sync committee periods.
|
||||
* If the validator is in the current sync committee period, then they perform the responsibilities below for sync committee rewards.
|
||||
* If the validator is in the next sync committee period, they should wait until the next `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` boundary and then perform the responsibilities throughout that period.
|
||||
- Upon (re)syncing the chain and upon sync committee period boundaries, check for assignments in the current and next sync committee periods.
|
||||
- If the validator is in the current sync committee period, then they perform the responsibilities below for sync committee rewards.
|
||||
- If the validator is in the next sync committee period, they should wait until the next `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` boundary and then perform the responsibilities throughout that period.
|
||||
|
||||
## Beacon chain responsibilities
|
||||
|
||||
@@ -424,16 +419,16 @@ def get_contribution_and_proof_signature(state: BeaconState,
|
||||
The sync committee subnets need special care to ensure stability given the relatively low number of validators involved in the sync committee at any particular time.
|
||||
To provide this stability, a validator must do the following:
|
||||
|
||||
* Maintain advertisement of the subnet the validator in the sync committee is assigned to in their node's ENR as soon as they have joined the subnet.
|
||||
Subnet assignments are known `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` epochs in advance and can be computed with `compute_subnets_for_sync_committee` defined above.
|
||||
ENR advertisement is indicated by setting the appropriate bit(s) of the bitfield found under the `syncnets` key in the ENR corresponding to the derived `subnet_id`(s).
|
||||
Any bits modified for the sync committee responsibilities are unset in the ENR once the node no longer has any validators in the subcommittee.
|
||||
- Maintain advertisement of the subnet the validator in the sync committee is assigned to in their node's ENR as soon as they have joined the subnet.
|
||||
Subnet assignments are known `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` epochs in advance and can be computed with `compute_subnets_for_sync_committee` defined above.
|
||||
ENR advertisement is indicated by setting the appropriate bit(s) of the bitfield found under the `syncnets` key in the ENR corresponding to the derived `subnet_id`(s).
|
||||
Any bits modified for the sync committee responsibilities are unset in the ENR once the node no longer has any validators in the subcommittee.
|
||||
|
||||
*Note*: The first sync committee from phase 0 to the Altair fork will not be known until the fork happens, which implies subnet assignments are not known until then.
|
||||
Early sync committee members should listen for topic subscriptions from peers and employ discovery via the ENR advertisements near the fork boundary to form initial subnets.
|
||||
Some early sync committee rewards may be missed while the initial subnets form.
|
||||
Early sync committee members should listen for topic subscriptions from peers and employ discovery via the ENR advertisements near the fork boundary to form initial subnets.
|
||||
Some early sync committee rewards may be missed while the initial subnets form.
|
||||
|
||||
* To join a sync committee subnet, select a random number of epochs before the end of the current sync committee period between 1 and `SYNC_COMMITTEE_SUBNET_COUNT`, inclusive.
|
||||
Validators should join their member subnet at the beginning of the epoch they have randomly selected.
|
||||
For example, if the next sync committee period starts at epoch `853,248` and the validator randomly selects an offset of `3`, they should join the subnet at the beginning of epoch `853,245`.
|
||||
Validators should leverage the lookahead period on sync committee assignments so that they can join the appropriate subnets ahead of their assigned sync committee period.
|
||||
- To join a sync committee subnet, select a random number of epochs before the end of the current sync committee period between 1 and `SYNC_COMMITTEE_SUBNET_COUNT`, inclusive.
|
||||
Validators should join their member subnet at the beginning of the epoch they have randomly selected.
|
||||
For example, if the next sync committee period starts at epoch `853,248` and the validator randomly selects an offset of `3`, they should join the subnet at the beginning of epoch `853,245`.
|
||||
Validators should leverage the lookahead period on sync committee assignments so that they can join the appropriate subnets ahead of their assigned sync committee period.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Bellatrix -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -45,35 +41,35 @@
|
||||
- [Epoch processing](#epoch-processing)
|
||||
- [Slashings](#slashings)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
This upgrade adds transaction execution to the beacon chain as part of Bellatrix upgrade.
|
||||
|
||||
Additionally, this upgrade introduces the following minor changes:
|
||||
* Penalty parameter updates to their planned maximally punitive values
|
||||
|
||||
- Penalty parameter updates to their planned maximally punitive values
|
||||
|
||||
## Custom types
|
||||
|
||||
*Note*: The `Transaction` type is a stub which is not final.
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `Transaction` | `ByteList[MAX_BYTES_PER_TRANSACTION]` | either a [typed transaction envelope](https://eips.ethereum.org/EIPS/eip-2718#opaque-byte-array-rather-than-an-rlp-array) or a legacy transaction|
|
||||
| `ExecutionAddress` | `Bytes20` | Address of account on the execution layer |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ------------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `Transaction` | `ByteList[MAX_BYTES_PER_TRANSACTION]` | either a [typed transaction envelope](https://eips.ethereum.org/EIPS/eip-2718#opaque-byte-array-rather-than-an-rlp-array) or a legacy transaction |
|
||||
| `ExecutionAddress` | `Bytes20` | Address of account on the execution layer |
|
||||
|
||||
## Preset
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_BYTES_PER_TRANSACTION` | `uint64(2**30)` (= 1,073,741,824) |
|
||||
| `MAX_TRANSACTIONS_PER_PAYLOAD` | `uint64(2**20)` (= 1,048,576) |
|
||||
| `BYTES_PER_LOGS_BLOOM` | `uint64(2**8)` (= 256) |
|
||||
| `MAX_EXTRA_DATA_BYTES` | `2**5` (= 32) |
|
||||
| Name | Value |
|
||||
| ------------------------------ | --------------------------------- |
|
||||
| `MAX_BYTES_PER_TRANSACTION` | `uint64(2**30)` (= 1,073,741,824) |
|
||||
| `MAX_TRANSACTIONS_PER_PAYLOAD` | `uint64(2**20)` (= 1,048,576) |
|
||||
| `BYTES_PER_LOGS_BLOOM` | `uint64(2**8)` (= 256) |
|
||||
| `MAX_EXTRA_DATA_BYTES` | `2**5` (= 32) |
|
||||
|
||||
### Updated penalty values
|
||||
|
||||
@@ -81,21 +77,21 @@ Bellatrix updates a few configuration values to move penalty parameters to their
|
||||
|
||||
*Note*: The spec does *not* override previous configuration values but instead creates new values and replaces usage throughout.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `INACTIVITY_PENALTY_QUOTIENT_BELLATRIX` | `uint64(2**24)` (= 16,777,216) |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX` | `uint64(2**5)` (= 32) |
|
||||
| `PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX` | `uint64(3)` |
|
||||
| Name | Value |
|
||||
| -------------------------------------------- | ------------------------------ |
|
||||
| `INACTIVITY_PENALTY_QUOTIENT_BELLATRIX` | `uint64(2**24)` (= 16,777,216) |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX` | `uint64(2**5)` (= 32) |
|
||||
| `PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX` | `uint64(3)` |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Transition settings
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `TERMINAL_TOTAL_DIFFICULTY` | `58750000000000000000000` (Estimated: Sept 15, 2022)|
|
||||
| `TERMINAL_BLOCK_HASH` | `Hash32()` |
|
||||
| `TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH` | `FAR_FUTURE_EPOCH` |
|
||||
| Name | Value |
|
||||
| -------------------------------------- | ---------------------------------------------------- |
|
||||
| `TERMINAL_TOTAL_DIFFICULTY` | `58750000000000000000000` (Estimated: Sept 15, 2022) |
|
||||
| `TERMINAL_BLOCK_HASH` | `Hash32()` |
|
||||
| `TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH` | `FAR_FUTURE_EPOCH` |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -318,8 +314,8 @@ class NewPayloadRequest(object):
|
||||
|
||||
The implementation-dependent `ExecutionEngine` protocol encapsulates the execution sub-system logic via:
|
||||
|
||||
* a state object `self.execution_state` of type `ExecutionState`
|
||||
* a notification function `self.notify_new_payload` which may apply changes to the `self.execution_state`
|
||||
- a state object `self.execution_state` of type `ExecutionState`
|
||||
- a notification function `self.notify_new_payload` which may apply changes to the `self.execution_state`
|
||||
|
||||
The body of these functions are implementation dependent.
|
||||
The Engine API may be used to implement this and similarly defined functions via an external execution engine.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Bellatrix -- Fork Choice
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -22,8 +18,7 @@
|
||||
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
|
||||
- [`on_block`](#on_block)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -33,9 +28,9 @@ This is the modification of the fork choice according to the executable beacon c
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `PayloadId` | `Bytes8` | Identifier of a payload building process |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ----------- | -------------- | ---------------------------------------- |
|
||||
| `PayloadId` | `Bytes8` | Identifier of a payload building process |
|
||||
|
||||
## Protocols
|
||||
|
||||
@@ -49,10 +44,11 @@ The Engine API may be used to implement it with an external execution engine.
|
||||
#### `notify_forkchoice_updated`
|
||||
|
||||
This function performs three actions *atomically*:
|
||||
* Re-organizes the execution payload chain and corresponding state to make `head_block_hash` the head.
|
||||
* Updates safe block hash with the value provided by `safe_block_hash` parameter.
|
||||
* Applies finality to the execution state: it irreversibly persists the chain of all execution payloads
|
||||
and corresponding state, up to and including `finalized_block_hash`.
|
||||
|
||||
- Re-organizes the execution payload chain and corresponding state to make `head_block_hash` the head.
|
||||
- Updates safe block hash with the value provided by `safe_block_hash` parameter.
|
||||
- Applies finality to the execution state: it irreversibly persists the chain of all execution payloads
|
||||
and corresponding state, up to and including `finalized_block_hash`.
|
||||
|
||||
Additionally, if `payload_attributes` is provided, this function sets in motion a payload build process on top of
|
||||
`head_block_hash` and returns an identifier of initiated process.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Bellatrix -- Fork Logic
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -15,8 +11,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -24,10 +19,10 @@ This document describes the process of Bellatrix upgrade.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `BELLATRIX_FORK_VERSION` | `Version('0x02000000')` |
|
||||
| `BELLATRIX_FORK_EPOCH` | `Epoch(144896)` (Sept 6, 2022, 11:34:47am UTC) |
|
||||
| Name | Value |
|
||||
| ------------------------ | ---------------------------------------------- |
|
||||
| `BELLATRIX_FORK_VERSION` | `Version('0x02000000')` |
|
||||
| `BELLATRIX_FORK_EPOCH` | `Epoch(144896)` (Sept 6, 2022, 11:34:47am UTC) |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
# Bellatrix -- Networking
|
||||
|
||||
## Table of contents
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Bellatrix](#modifications-in-bellatrix)
|
||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||
- [Topics and messages](#topics-and-messages)
|
||||
- [Global topics](#global-topics)
|
||||
- [`beacon_block`](#beacon_block)
|
||||
- [Transitioning the gossip](#transitioning-the-gossip)
|
||||
- [The Req/Resp domain](#the-reqresp-domain)
|
||||
- [Messages](#messages)
|
||||
- [BeaconBlocksByRange v2](#beaconblocksbyrange-v2)
|
||||
- [BeaconBlocksByRoot v2](#beaconblocksbyroot-v2)
|
||||
- [Gossipsub](#gossipsub)
|
||||
- [Why was the max gossip message size increased at Bellatrix?](#why-was-the-max-gossip-message-size-increased-at-bellatrix)
|
||||
- [Req/Resp](#reqresp)
|
||||
- [Why was the max chunk response size increased at Bellatrix?](#why-was-the-max-chunk-response-size-increased-at-bellatrix)
|
||||
- [Why allow invalid payloads on the P2P network?](#why-allow-invalid-payloads-on-the-p2p-network)
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Bellatrix](#modifications-in-bellatrix)
|
||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||
- [Topics and messages](#topics-and-messages)
|
||||
- [Global topics](#global-topics)
|
||||
- [`beacon_block`](#beacon_block)
|
||||
- [Transitioning the gossip](#transitioning-the-gossip)
|
||||
- [The Req/Resp domain](#the-reqresp-domain)
|
||||
- [Messages](#messages)
|
||||
- [BeaconBlocksByRange v2](#beaconblocksbyrange-v2)
|
||||
- [BeaconBlocksByRoot v2](#beaconblocksbyroot-v2)
|
||||
- [Design decision rationale](#design-decision-rationale)
|
||||
- [Gossipsub](#gossipsub)
|
||||
- [Why was the max gossip message size increased at Bellatrix?](#why-was-the-max-gossip-message-size-increased-at-bellatrix)
|
||||
- [Req/Resp](#reqresp)
|
||||
- [Why was the max chunk response size increased at Bellatrix?](#why-was-the-max-chunk-response-size-increased-at-bellatrix)
|
||||
- [Why allow invalid payloads on the P2P network?](#why-allow-invalid-payloads-on-the-p2p-network)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -52,8 +46,8 @@ The derivation of the `message-id` remains stable.
|
||||
|
||||
The new topics along with the type of the `data` field of a gossipsub message are given in this table:
|
||||
|
||||
| Name | Message Type |
|
||||
| - | - |
|
||||
| Name | Message Type |
|
||||
| -------------- | ------------------------------ |
|
||||
| `beacon_block` | `SignedBeaconBlock` (modified) |
|
||||
|
||||
Note that the `ForkDigestValue` path segment of the topic separates the old and the new `beacon_block` topics.
|
||||
@@ -82,11 +76,11 @@ then validate the following:
|
||||
- _[REJECT]_ The block's execution payload timestamp is correct with respect to the slot
|
||||
-- i.e. `execution_payload.timestamp == compute_timestamp_at_slot(state, block.slot)`.
|
||||
- If `execution_payload` verification of block's parent by an execution node is *not* complete:
|
||||
- _[REJECT]_ The block's parent (defined by `block.parent_root`) passes all
|
||||
validation (excluding execution node verification of the `block.body.execution_payload`).
|
||||
- _[REJECT]_ The block's parent (defined by `block.parent_root`) passes all
|
||||
validation (excluding execution node verification of the `block.body.execution_payload`).
|
||||
- Otherwise:
|
||||
- _[IGNORE]_ The block's parent (defined by `block.parent_root`) passes all
|
||||
validation (including execution node verification of the `block.body.execution_payload`).
|
||||
- _[IGNORE]_ The block's parent (defined by `block.parent_root`) passes all
|
||||
validation (including execution node verification of the `block.body.execution_payload`).
|
||||
|
||||
The following gossip validation from prior specifications MUST NOT be applied if the execution is
|
||||
enabled for the block -- i.e. `is_execution_enabled(state, block.body)`:
|
||||
@@ -120,12 +114,12 @@ Bellatrix fork-digest is introduced to the `context` enum to specify Bellatrix b
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
|
||||
##### BeaconBlocksByRoot v2
|
||||
@@ -137,12 +131,12 @@ Bellatrix fork-digest is introduced to the `context` enum to specify Bellatrix b
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
|
||||
# Design decision rationale
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Bellatrix -- Honest Validator
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -20,8 +16,7 @@
|
||||
- [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody)
|
||||
- [ExecutionPayload](#executionpayload)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -118,11 +113,11 @@ All validator responsibilities remain unchanged other than those noted below. Na
|
||||
To obtain an execution payload, a block proposer building a block on top of a `state` must take the following actions:
|
||||
|
||||
1. Set `payload_id = prepare_execution_payload(state, pow_chain, safe_block_hash, finalized_block_hash, suggested_fee_recipient, execution_engine)`, where:
|
||||
* `state` is the state object after applying `process_slots(state, slot)` transition to the resulting state of the parent block processing
|
||||
* `pow_chain` is a `Dict[Hash32, PowBlock]` dictionary that abstractly represents all blocks in the PoW chain with block hash as the dictionary key
|
||||
* `safe_block_hash` is the return value of the `get_safe_execution_block_hash(store: Store)` function call
|
||||
* `finalized_block_hash` is the block hash of the latest finalized execution payload (`Hash32()` if none yet finalized)
|
||||
* `suggested_fee_recipient` is the value suggested to be used for the `fee_recipient` field of the execution payload
|
||||
- `state` is the state object after applying `process_slots(state, slot)` transition to the resulting state of the parent block processing
|
||||
- `pow_chain` is a `Dict[Hash32, PowBlock]` dictionary that abstractly represents all blocks in the PoW chain with block hash as the dictionary key
|
||||
- `safe_block_hash` is the return value of the `get_safe_execution_block_hash(store: Store)` function call
|
||||
- `finalized_block_hash` is the block hash of the latest finalized execution payload (`Hash32()` if none yet finalized)
|
||||
- `suggested_fee_recipient` is the value suggested to be used for the `fee_recipient` field of the execution payload
|
||||
|
||||
```python
|
||||
def prepare_execution_payload(state: BeaconState,
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -39,18 +35,17 @@
|
||||
- [Modified `process_operations`](#modified-process_operations)
|
||||
- [New `process_bls_to_execution_change`](#new-process_bls_to_execution_change)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
Capella is a consensus-layer upgrade containing a number of features related
|
||||
to validator withdrawals. Including:
|
||||
|
||||
* Automatic withdrawals of `withdrawable` validators.
|
||||
* Partial withdrawals sweep for validators with 0x01 withdrawal
|
||||
- Automatic withdrawals of `withdrawable` validators.
|
||||
- Partial withdrawals sweep for validators with 0x01 withdrawal
|
||||
credentials and balances in excess of `MAX_EFFECTIVE_BALANCE`.
|
||||
* Operation to change from `BLS_WITHDRAWAL_PREFIX` to
|
||||
- Operation to change from `BLS_WITHDRAWAL_PREFIX` to
|
||||
`ETH1_ADDRESS_WITHDRAWAL_PREFIX` versioned withdrawal credentials to enable withdrawals for a validator.
|
||||
|
||||
Another new feature is the new independent state and block historical accumulators
|
||||
@@ -62,35 +57,35 @@ beyond the state and the blocks.
|
||||
|
||||
We define the following Python custom types for type hinting and readability:
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `WithdrawalIndex` | `uint64` | an index of a `Withdrawal` |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ----------------- | -------------- | -------------------------- |
|
||||
| `WithdrawalIndex` | `uint64` | an index of a `Withdrawal` |
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| -------------------------------- | -------------------------- |
|
||||
| `DOMAIN_BLS_TO_EXECUTION_CHANGE` | `DomainType('0x0A000000')` |
|
||||
|
||||
## Preset
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ------------------------------ | ------------- |
|
||||
| `MAX_BLS_TO_EXECUTION_CHANGES` | `2**4` (= 16) |
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| ----------------------------- | --------------------- | ----------------------------------------------------- |
|
||||
| `MAX_WITHDRAWALS_PER_PAYLOAD` | `uint64(2**4)` (= 16) | Maximum amount of withdrawals allowed in each payload |
|
||||
|
||||
### Withdrawals processing
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP` | `16384` (= 2**14 ) |
|
||||
| Name | Value |
|
||||
| -------------------------------------- | -------------------- |
|
||||
| `MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP` | `16384` (= 2\*\*14 ) |
|
||||
|
||||
## Containers
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella -- Fork Choice
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -16,8 +12,7 @@
|
||||
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
|
||||
- [`on_block`](#on_block)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella -- Fork Logic
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -15,8 +11,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -24,10 +19,10 @@ This document describes the process of the Capella upgrade.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `CAPELLA_FORK_VERSION` | `Version('0x03000000')` |
|
||||
| `CAPELLA_FORK_EPOCH` | `Epoch(194048)` (April 12, 2023, 10:27:35pm UTC) |
|
||||
| Name | Value |
|
||||
| ---------------------- | ------------------------------------------------ |
|
||||
| `CAPELLA_FORK_VERSION` | `Version('0x03000000')` |
|
||||
| `CAPELLA_FORK_EPOCH` | `Epoch(194048)` (April 12, 2023, 10:27:35pm UTC) |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
# Capella Light Client -- Fork Logic
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Upgrading light client data](#upgrading-light-client-data)
|
||||
- [Upgrading the store](#upgrading-the-store)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
# Capella Light Client -- Full Node
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Modified `block_to_light_client_header`](#modified-block_to_light_client_header)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella Light Client -- Networking
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Networking](#networking)
|
||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||
@@ -19,8 +15,7 @@
|
||||
- [GetLightClientFinalityUpdate](#getlightclientfinalityupdate)
|
||||
- [GetLightClientOptimisticUpdate](#getlightclientoptimisticupdate)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Networking
|
||||
|
||||
@@ -34,17 +29,17 @@ The [Altair light client networking specification](../../altair/light-client/p2p
|
||||
|
||||
###### `light_client_finality_update`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientFinalityUpdate` |
|
||||
| `fork_version` | Message SSZ type |
|
||||
| ------------------------------------------------------ | ----------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientFinalityUpdate` |
|
||||
|
||||
###### `light_client_optimistic_update`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
@@ -58,37 +53,37 @@ The [Altair light client networking specification](../../altair/light-client/p2p
|
||||
|
||||
##### GetLightClientBootstrap
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientBootstrap` |
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientBootstrap` |
|
||||
|
||||
##### LightClientUpdatesByRange
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientUpdate` |
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
| ------------------------------------------------------ | --------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientUpdate` |
|
||||
|
||||
##### GetLightClientFinalityUpdate
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientFinalityUpdate` |
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ----------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` and later | `capella.LightClientFinalityUpdate` |
|
||||
|
||||
##### GetLightClientOptimisticUpdate
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella Light Client -- Sync Protocol
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -15,27 +11,27 @@
|
||||
- [`get_lc_execution_root`](#get_lc_execution_root)
|
||||
- [Modified `is_valid_light_client_header`](#modified-is_valid_light_client_header)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
This upgrade adds information about the execution payload to light client data as part of the Capella upgrade. It extends the [Altair Light Client specifications](../../altair/light-client/sync-protocol.md). The [fork document](./fork.md) explains how to upgrade existing Altair based deployments to Capella.
|
||||
|
||||
Additional documents describes the impact of the upgrade on certain roles:
|
||||
|
||||
- [Full node](./full-node.md)
|
||||
- [Networking](./p2p-interface.md)
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ----------------- | ------------------------------------------------------ | ------------------------------------------------------------- |
|
||||
| `ExecutionBranch` | `Vector[Bytes32, floorlog2(EXECUTION_PAYLOAD_GINDEX)]` | Merkle branch of `execution_payload` within `BeaconBlockBody` |
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| -------------------------- | -------------------------------------------------------------------- |
|
||||
| `EXECUTION_PAYLOAD_GINDEX` | `get_generalized_index(BeaconBlockBody, 'execution_payload')` (= 25) |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella -- Networking
|
||||
|
||||
### Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Capella](#modifications-in-capella)
|
||||
@@ -19,8 +15,7 @@
|
||||
- [BeaconBlocksByRange v2](#beaconblocksbyrange-v2)
|
||||
- [BeaconBlocksByRoot v2](#beaconblocksbyroot-v2)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -40,10 +35,10 @@ Topics follow the same specification as in prior upgrades. All existing topics r
|
||||
|
||||
The new topics along with the type of the `data` field of a gossipsub message are given in this table:
|
||||
|
||||
| Name | Message Type |
|
||||
| - | - |
|
||||
| `beacon_block` | `SignedBeaconBlock` (modified) |
|
||||
| `bls_to_execution_change` | `SignedBLSToExecutionChange` |
|
||||
| Name | Message Type |
|
||||
| ------------------------- | ------------------------------ |
|
||||
| `beacon_block` | `SignedBeaconBlock` (modified) |
|
||||
| `bls_to_execution_change` | `SignedBLSToExecutionChange` |
|
||||
|
||||
Note that the `ForkDigestValue` path segment of the topic separates the old and the new `beacon_block` topics.
|
||||
|
||||
@@ -86,14 +81,14 @@ The Capella fork-digest is introduced to the `context` enum to specify Capella b
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||
|
||||
##### BeaconBlocksByRoot v2
|
||||
|
||||
@@ -103,12 +98,11 @@ The Capella fork-digest is introduced to the `context` enum to specify Capella b
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||
|
||||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Capella -- Honest Validator
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -21,8 +17,7 @@
|
||||
- [Enabling validator withdrawals](#enabling-validator-withdrawals)
|
||||
- [Changing from BLS to execution withdrawal credentials](#changing-from-bls-to-execution-withdrawal-credentials)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -44,57 +40,56 @@
|
||||
- [Epoch processing](#epoch-processing)
|
||||
- [Registry updates](#registry-updates)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
Deneb is a consensus-layer upgrade containing a number of features. Including:
|
||||
|
||||
* [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788): Beacon block root in the EVM
|
||||
* [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Shard Blob Transactions scale data-availability of Ethereum in a simple, forwards-compatible manner
|
||||
* [EIP-7044](https://eips.ethereum.org/EIPS/eip-7044): Perpetually Valid Signed Voluntary Exits
|
||||
* [EIP-7045](https://eips.ethereum.org/EIPS/eip-7045): Increase Max Attestation Inclusion Slot
|
||||
* [EIP-7514](https://eips.ethereum.org/EIPS/eip-7514): Add Max Epoch Churn Limit
|
||||
- [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788): Beacon block root in the EVM
|
||||
- [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Shard Blob Transactions scale data-availability of Ethereum in a simple, forwards-compatible manner
|
||||
- [EIP-7044](https://eips.ethereum.org/EIPS/eip-7044): Perpetually Valid Signed Voluntary Exits
|
||||
- [EIP-7045](https://eips.ethereum.org/EIPS/eip-7045): Increase Max Attestation Inclusion Slot
|
||||
- [EIP-7514](https://eips.ethereum.org/EIPS/eip-7514): Add Max Epoch Churn Limit
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `VersionedHash` | `Bytes32` | *[New in Deneb:EIP4844]* |
|
||||
| `BlobIndex` | `uint64` | *[New in Deneb:EIP4844]* |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| --------------- | -------------- | ------------------------ |
|
||||
| `VersionedHash` | `Bytes32` | *[New in Deneb:EIP4844]* |
|
||||
| `BlobIndex` | `uint64` | *[New in Deneb:EIP4844]* |
|
||||
|
||||
## Constants
|
||||
|
||||
### Blob
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ---------------------------- | ---------------- |
|
||||
| `VERSIONED_HASH_VERSION_KZG` | `Bytes1('0x01')` |
|
||||
|
||||
## Preset
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| -------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `MAX_BLOB_COMMITMENTS_PER_BLOCK` | `uint64(2**12)` (= 4096) | *[New in Deneb:EIP4844]* hardfork independent fixed theoretical limit same as `TARGET_BLOB_GAS_PER_BLOCK` (see EIP 4844) |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MAX_BLOBS_PER_BLOCK` | `uint64(6)` | *[New in Deneb:EIP4844]* maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` |
|
||||
| Name | Value | Description |
|
||||
| --------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `MAX_BLOBS_PER_BLOCK` | `uint64(6)` | *[New in Deneb:EIP4844]* maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` |
|
||||
|
||||
*Note*: The blob transactions are packed into the execution payload by the EL/builder with their corresponding blobs being independently transmitted
|
||||
and are limited by `MAX_BLOB_GAS_PER_BLOCK // GAS_PER_BLOB`. However the CL limit is independently defined by `MAX_BLOBS_PER_BLOCK`.
|
||||
|
||||
### Validator cycle
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| -------------------------------------- | -------------------- |
|
||||
| `MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT` | `uint64(2**3)` (= 8) |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb -- Fork Choice
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Containers](#containers)
|
||||
@@ -14,8 +10,7 @@
|
||||
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
|
||||
- [`on_block`](#on_block)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb -- Fork Logic
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -15,8 +11,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -26,10 +21,10 @@ This document describes the process of Deneb upgrade.
|
||||
|
||||
Warning: this configuration is not definitive.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `DENEB_FORK_VERSION` | `Version('0x04000000')` |
|
||||
| `DENEB_FORK_EPOCH` | `Epoch(269568)` (March 13, 2024, 01:55:35pm UTC) |
|
||||
| Name | Value |
|
||||
| -------------------- | ------------------------------------------------ |
|
||||
| `DENEB_FORK_VERSION` | `Version('0x04000000')` |
|
||||
| `DENEB_FORK_EPOCH` | `Epoch(269568)` (March 13, 2024, 01:55:35pm UTC) |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
# Deneb Light Client -- Fork Logic
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Upgrading light client data](#upgrading-light-client-data)
|
||||
- [Upgrading the store](#upgrading-the-store)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
# Deneb Light Client -- Full Node
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Modified `block_to_light_client_header`](#modified-block_to_light_client_header)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb Light Client -- Networking
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Networking](#networking)
|
||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||
@@ -19,8 +15,7 @@
|
||||
- [GetLightClientFinalityUpdate](#getlightclientfinalityupdate)
|
||||
- [GetLightClientOptimisticUpdate](#getlightclientoptimisticupdate)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Networking
|
||||
|
||||
@@ -34,10 +29,10 @@ The [Capella light client networking specification](../../capella/light-client/p
|
||||
|
||||
###### `light_client_finality_update`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
|--------------------------------------------------------|-------------------------------------|
|
||||
| ------------------------------------------------------ | ----------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientFinalityUpdate` |
|
||||
@@ -45,10 +40,10 @@ The [Capella light client networking specification](../../capella/light-client/p
|
||||
|
||||
###### `light_client_optimistic_update`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
|--------------------------------------------------------|---------------------------------------|
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientOptimisticUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientOptimisticUpdate` |
|
||||
@@ -60,32 +55,32 @@ The [Capella light client networking specification](../../capella/light-client/p
|
||||
|
||||
##### GetLightClientBootstrap
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
|--------------------------------------------------------|------------------------------------|
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientBootstrap` |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.LightClientBootstrap` |
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientBootstrap` |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.LightClientBootstrap` |
|
||||
|
||||
##### LightClientUpdatesByRange
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
|--------------------------------------------------------|----------------------------------|
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientUpdate` |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.LightClientUpdate` |
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
| ------------------------------------------------------ | --------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientUpdate` |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.LightClientUpdate` |
|
||||
|
||||
##### GetLightClientFinalityUpdate
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
|--------------------------------------------------------|-------------------------------------|
|
||||
| ------------------------------------------------------ | ----------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientFinalityUpdate` |
|
||||
@@ -93,10 +88,10 @@ The [Capella light client networking specification](../../capella/light-client/p
|
||||
|
||||
##### GetLightClientOptimisticUpdate
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
|--------------------------------------------------------|---------------------------------------|
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientOptimisticUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientOptimisticUpdate` |
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
# Deneb Light Client -- Sync Protocol
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Modified `get_lc_execution_root`](#modified-get_lc_execution_root)
|
||||
- [Modified `is_valid_light_client_header`](#modified-is_valid_light_client_header)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
This upgrade updates light client data to include the Deneb changes to the [`ExecutionPayload`](../beacon-chain.md) structure. It extends the [Capella Light Client specifications](../../capella/light-client/sync-protocol.md). The [fork document](./fork.md) explains how to upgrade existing Capella based deployments to Deneb.
|
||||
|
||||
Additional documents describes the impact of the upgrade on certain roles:
|
||||
|
||||
- [Full node](./full-node.md)
|
||||
- [Networking](./p2p-interface.md)
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb -- Networking
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Deneb](#modifications-in-deneb)
|
||||
@@ -36,8 +32,7 @@
|
||||
- [Design decision rationale](#design-decision-rationale)
|
||||
- [Why are blobs relayed as a sidecar, separate from beacon blocks?](#why-are-blobs-relayed-as-a-sidecar-separate-from-beacon-blocks)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -55,20 +50,20 @@ The specification of these changes continues in the same format as the network s
|
||||
|
||||
*[New in Deneb:EIP4844]*
|
||||
|
||||
| Name | Value | Description |
|
||||
|------------------------------------------|-----------------------------------|---------------------------------------------------------------------|
|
||||
| `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH` | `uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')) + 1 + ceillog2(MAX_BLOB_COMMITMENTS_PER_BLOCK))` (= 17) | <!-- predefined --> Merkle proof depth for `blob_kzg_commitments` list item |
|
||||
| Name | Value | Description |
|
||||
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH` | `uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')) + 1 + ceillog2(MAX_BLOB_COMMITMENTS_PER_BLOCK))` (= 17) | <!-- predefined --> Merkle proof depth for `blob_kzg_commitments` list item |
|
||||
|
||||
### Configuration
|
||||
|
||||
*[New in Deneb:EIP4844]*
|
||||
|
||||
| Name | Value | Description |
|
||||
|------------------------------------------|-----------------------------------|---------------------------------------------------------------------|
|
||||
| `MAX_REQUEST_BLOCKS_DENEB` | `2**7` (= 128) | Maximum number of blocks in a single request |
|
||||
| `MAX_REQUEST_BLOB_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK` | Maximum number of blob sidecars in a single request |
|
||||
| `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve blob sidecars |
|
||||
| `BLOB_SIDECAR_SUBNET_COUNT` | `6` | The number of blob sidecar subnets used in the gossipsub protocol. |
|
||||
| Name | Value | Description |
|
||||
| --------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------ |
|
||||
| `MAX_REQUEST_BLOCKS_DENEB` | `2**7` (= 128) | Maximum number of blocks in a single request |
|
||||
| `MAX_REQUEST_BLOB_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK` | Maximum number of blob sidecars in a single request |
|
||||
| `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve blob sidecars |
|
||||
| `BLOB_SIDECAR_SUBNET_COUNT` | `6` | The number of blob sidecar subnets used in the gossipsub protocol. |
|
||||
|
||||
### Containers
|
||||
|
||||
@@ -132,8 +127,8 @@ The derivation of the `message-id` remains stable.
|
||||
|
||||
The new topics along with the type of the `data` field of a gossipsub message are given in this table:
|
||||
|
||||
| Name | Message Type |
|
||||
| - | - |
|
||||
| Name | Message Type |
|
||||
| -------------------------- | ------------------------------------ |
|
||||
| `blob_sidecar_{subnet_id}` | `BlobSidecar` [New in Deneb:EIP4844] |
|
||||
|
||||
##### Global topics
|
||||
@@ -155,16 +150,16 @@ New validation:
|
||||
|
||||
The following validation is removed:
|
||||
|
||||
* _[IGNORE]_ `aggregate.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
- _[IGNORE]_ `aggregate.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `aggregate.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= aggregate.data.slot`
|
||||
(a client MAY queue future aggregates for processing at the appropriate slot).
|
||||
|
||||
The following validations are added in its place:
|
||||
|
||||
* _[IGNORE]_ `aggregate.data.slot` is equal to or earlier than the `current_slot` (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
- _[IGNORE]_ `aggregate.data.slot` is equal to or earlier than the `current_slot` (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `aggregate.data.slot <= current_slot`
|
||||
(a client MAY queue future aggregates for processing at the appropriate slot).
|
||||
* _[IGNORE]_ the epoch of `aggregate.data.slot` is either the current or previous epoch
|
||||
- _[IGNORE]_ the epoch of `aggregate.data.slot` is either the current or previous epoch
|
||||
(with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `compute_epoch_at_slot(aggregate.data.slot) in (get_previous_epoch(state), get_current_epoch(state))`
|
||||
|
||||
@@ -197,10 +192,10 @@ The gossip `ForkDigestValue` is determined based on `compute_fork_version(comput
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------------|---------------------|
|
||||
| ------------------------------ | ------------------- |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.BlobSidecar` |
|
||||
|
||||
###### Blob retrieval via local execution layer client
|
||||
@@ -210,8 +205,8 @@ Honest nodes SHOULD query `engine_getBlobsV1` as soon as they receive a valid go
|
||||
|
||||
When clients use the local execution layer to retrieve blobs, they MUST behave as if the corresponding `blob_sidecar` had been received via gossip. In particular they MUST:
|
||||
|
||||
* Publish the corresponding `blob_sidecar` on the `blob_sidecar_{subnet_id}` subnet.
|
||||
* Update gossip rule related data structures (i.e. update the anti-equivocation cache).
|
||||
- Publish the corresponding `blob_sidecar` on the `blob_sidecar_{subnet_id}` subnet.
|
||||
- Update gossip rule related data structures (i.e. update the anti-equivocation cache).
|
||||
|
||||
##### Attestation subnets
|
||||
|
||||
@@ -221,16 +216,16 @@ When clients use the local execution layer to retrieve blobs, they MUST behave a
|
||||
|
||||
The following validation is removed:
|
||||
|
||||
* _[IGNORE]_ `attestation.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
- _[IGNORE]_ `attestation.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= attestation.data.slot`
|
||||
(a client MAY queue future attestations for processing at the appropriate slot).
|
||||
|
||||
The following validations are added in its place:
|
||||
|
||||
* _[IGNORE]_ `attestation.data.slot` is equal to or earlier than the `current_slot` (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
- _[IGNORE]_ `attestation.data.slot` is equal to or earlier than the `current_slot` (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `attestation.data.slot <= current_slot`
|
||||
(a client MAY queue future attestation for processing at the appropriate slot).
|
||||
* _[IGNORE]_ the epoch of `attestation.data.slot` is either the current or previous epoch
|
||||
- _[IGNORE]_ the epoch of `attestation.data.slot` is either the current or previous epoch
|
||||
(with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `compute_epoch_at_slot(attestation.data.slot) in (get_previous_epoch(state), get_current_epoch(state))`
|
||||
|
||||
@@ -251,10 +246,10 @@ The Deneb fork-digest is introduced to the `context` enum to specify Deneb beaco
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
@@ -269,10 +264,10 @@ No more than `MAX_REQUEST_BLOCKS_DENEB` may be requested at a time.
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
@@ -363,10 +358,10 @@ For each `response_chunk`, a `ForkDigest`-context based on `compute_fork_version
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------------|---------------------|
|
||||
| ------------------------------ | ------------------- |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.BlobSidecar` |
|
||||
|
||||
##### BlobSidecarsByRoot v1
|
||||
@@ -417,10 +412,10 @@ For each `response_chunk`, a `ForkDigest`-context based on `compute_fork_version
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------------|---------------------|
|
||||
| ------------------------------ | ------------------- |
|
||||
| `DENEB_FORK_VERSION` and later | `deneb.BlobSidecar` |
|
||||
|
||||
## Design decision rationale
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb -- Polynomial Commitments
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -45,8 +41,7 @@
|
||||
- [`verify_blob_kzg_proof`](#verify_blob_kzg_proof)
|
||||
- [`verify_blob_kzg_proof_batch`](#verify_blob_kzg_proof_batch)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -58,52 +53,52 @@ Public functions MUST accept raw bytes as input and perform the required cryptog
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `G1Point` | `Bytes48` | |
|
||||
| `G2Point` | `Bytes96` | |
|
||||
| `KZGCommitment` | `Bytes48` | Validation: Perform [BLS standard's](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.5) "KeyValidate" check but do allow the identity point |
|
||||
| `KZGProof` | `Bytes48` | Same as for `KZGCommitment` |
|
||||
| `Blob` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]` | A basic data blob |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| --------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `G1Point` | `Bytes48` | |
|
||||
| `G2Point` | `Bytes96` | |
|
||||
| `KZGCommitment` | `Bytes48` | Validation: Perform [BLS standard's](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.5) "KeyValidate" check but do allow the identity point |
|
||||
| `KZGProof` | `Bytes48` | Same as for `KZGCommitment` |
|
||||
| `Blob` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]` | A basic data blob |
|
||||
|
||||
## Cryptographic types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| [`BLSFieldElement`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/deneb.py#L18-L19) | `uint256` | <!-- predefined-type --> A value in the finite field defined by `BLS_MODULUS` |
|
||||
| [`Polynomial`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/deneb.py#L22-L28) | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | <!-- predefined-type --> A polynomial in evaluation form |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| [`BLSFieldElement`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/deneb.py#L18-L19) | `uint256` | <!-- predefined-type --> A value in the finite field defined by `BLS_MODULUS` |
|
||||
| [`Polynomial`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/deneb.py#L22-L28) | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | <!-- predefined-type --> A polynomial in evaluation form |
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value | Notes |
|
||||
| - | - | - |
|
||||
| `BLS_MODULUS` | `52435875175126190479447740508185965837690552500527637822603658699938581184513` | Scalar field modulus of BLS12-381 |
|
||||
| `BYTES_PER_COMMITMENT` | `uint64(48)` | The number of bytes in a KZG commitment |
|
||||
| `BYTES_PER_PROOF` | `uint64(48)` | The number of bytes in a KZG proof |
|
||||
| `BYTES_PER_FIELD_ELEMENT` | `uint64(32)` | Bytes used to encode a BLS scalar field element |
|
||||
| `BYTES_PER_BLOB` | `uint64(BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB)` | The number of bytes in a blob |
|
||||
| `G1_POINT_AT_INFINITY` | `Bytes48(b'\xc0' + b'\x00' * 47)` | Serialized form of the point at infinity on the G1 group |
|
||||
| `KZG_ENDIANNESS` | `'big'` | The endianness of the field elements including blobs |
|
||||
| `PRIMITIVE_ROOT_OF_UNITY` | `7` | The primitive root of unity from which all roots of unity should be derived |
|
||||
| Name | Value | Notes |
|
||||
| ------------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `BLS_MODULUS` | `52435875175126190479447740508185965837690552500527637822603658699938581184513` | Scalar field modulus of BLS12-381 |
|
||||
| `BYTES_PER_COMMITMENT` | `uint64(48)` | The number of bytes in a KZG commitment |
|
||||
| `BYTES_PER_PROOF` | `uint64(48)` | The number of bytes in a KZG proof |
|
||||
| `BYTES_PER_FIELD_ELEMENT` | `uint64(32)` | Bytes used to encode a BLS scalar field element |
|
||||
| `BYTES_PER_BLOB` | `uint64(BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB)` | The number of bytes in a blob |
|
||||
| `G1_POINT_AT_INFINITY` | `Bytes48(b'\xc0' + b'\x00' * 47)` | Serialized form of the point at infinity on the G1 group |
|
||||
| `KZG_ENDIANNESS` | `'big'` | The endianness of the field elements including blobs |
|
||||
| `PRIMITIVE_ROOT_OF_UNITY` | `7` | The primitive root of unity from which all roots of unity should be derived |
|
||||
|
||||
## Preset
|
||||
|
||||
### Blob
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `FIELD_ELEMENTS_PER_BLOB` | `uint64(4096)` |
|
||||
| `FIAT_SHAMIR_PROTOCOL_DOMAIN` | `b'FSBLOBVERIFY_V1_'` |
|
||||
| Name | Value |
|
||||
| ----------------------------------- | --------------------- |
|
||||
| `FIELD_ELEMENTS_PER_BLOB` | `uint64(4096)` |
|
||||
| `FIAT_SHAMIR_PROTOCOL_DOMAIN` | `b'FSBLOBVERIFY_V1_'` |
|
||||
| `RANDOM_CHALLENGE_KZG_BATCH_DOMAIN` | `b'RCKZGBATCH___V1_'` |
|
||||
|
||||
### Trusted setup
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `KZG_SETUP_G2_LENGTH` | `65` |
|
||||
| Name | Value |
|
||||
| ----------------------- | ------------------------------------------ |
|
||||
| `KZG_SETUP_G2_LENGTH` | `65` |
|
||||
| `KZG_SETUP_G1_MONOMIAL` | `Vector[G1Point, FIELD_ELEMENTS_PER_BLOB]` |
|
||||
| `KZG_SETUP_G1_LAGRANGE` | `Vector[G1Point, FIELD_ELEMENTS_PER_BLOB]` |
|
||||
| `KZG_SETUP_G2_MONOMIAL` | `Vector[G2Point, KZG_SETUP_G2_LENGTH]` |
|
||||
| `KZG_SETUP_G2_MONOMIAL` | `Vector[G2Point, KZG_SETUP_G2_LENGTH]` |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Deneb -- Honest Validator
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -22,8 +18,7 @@
|
||||
- [Constructing the `BlobSidecar`s](#constructing-the-blobsidecars)
|
||||
- [Sidecar](#sidecar)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -110,18 +106,17 @@
|
||||
- [New `is_valid_switch_to_compounding_request`](#new-is_valid_switch_to_compounding_request)
|
||||
- [New `process_consolidation_request`](#new-process_consolidation_request)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
Electra is a consensus-layer upgrade containing a number of features. Including:
|
||||
|
||||
* [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Supply validator deposits on chain
|
||||
* [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002): Execution layer triggerable exits
|
||||
* [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Increase the MAX_EFFECTIVE_BALANCE
|
||||
* [EIP-7549](https://eips.ethereum.org/EIPS/eip-7549): Move committee index outside Attestation
|
||||
* [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691): Blob throughput increase
|
||||
- [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Supply validator deposits on chain
|
||||
- [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002): Execution layer triggerable exits
|
||||
- [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Increase the MAX_EFFECTIVE_BALANCE
|
||||
- [EIP-7549](https://eips.ethereum.org/EIPS/eip-7549): Move committee index outside Attestation
|
||||
- [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691): Blob throughput increase
|
||||
|
||||
*Note*: This specification is built upon [Deneb](../deneb/beacon-chain.md) and is under active development.
|
||||
|
||||
@@ -131,89 +126,89 @@ The following values are (non-configurable) constants used throughout the specif
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| ------------------------------------ | ------------------- | --------------------------------------------------------------------------------- |
|
||||
| `UNSET_DEPOSIT_REQUESTS_START_INDEX` | `uint64(2**64 - 1)` | *[New in Electra:EIP6110]* Value which indicates no start index has been assigned |
|
||||
| `FULL_EXIT_REQUEST_AMOUNT` | `uint64(0)` | *[New in Electra:EIP7002]* Withdrawal amount used to signal a full validator exit |
|
||||
| `FULL_EXIT_REQUEST_AMOUNT` | `uint64(0)` | *[New in Electra:EIP7002]* Withdrawal amount used to signal a full validator exit |
|
||||
|
||||
### Withdrawal prefixes
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| ------------------------------- | ---------------- | ----------------------------------------------------------------------------------- |
|
||||
| `COMPOUNDING_WITHDRAWAL_PREFIX` | `Bytes1('0x02')` | *[New in Electra:EIP7251]* Withdrawal credential prefix for a compounding validator |
|
||||
|
||||
### Execution layer triggered requests
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `DEPOSIT_REQUEST_TYPE` | `Bytes1('0x00')` |
|
||||
| `WITHDRAWAL_REQUEST_TYPE` | `Bytes1('0x01')` |
|
||||
| Name | Value |
|
||||
| ---------------------------- | ---------------- |
|
||||
| `DEPOSIT_REQUEST_TYPE` | `Bytes1('0x00')` |
|
||||
| `WITHDRAWAL_REQUEST_TYPE` | `Bytes1('0x01')` |
|
||||
| `CONSOLIDATION_REQUEST_TYPE` | `Bytes1('0x02')` |
|
||||
|
||||
## Preset
|
||||
|
||||
### Gwei values
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MIN_ACTIVATION_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) | *[New in Electra:EIP7251]* Minimum balance for a validator to become active |
|
||||
| Name | Value | Description |
|
||||
| ------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------- |
|
||||
| `MIN_ACTIVATION_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) | *[New in Electra:EIP7251]* Minimum balance for a validator to become active |
|
||||
| `MAX_EFFECTIVE_BALANCE_ELECTRA` | `Gwei(2**11 * 10**9)` (= 2048,000,000,000) | *[New in Electra:EIP7251]* Maximum effective balance for a compounding validator |
|
||||
|
||||
### Rewards and penalties
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| --------------------------------------- | ------------------------- |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA` | `uint64(2**12)` (= 4,096) |
|
||||
| `WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA` | `uint64(2**12)` (= 4,096) |
|
||||
|
||||
### State list lengths
|
||||
|
||||
| Name | Value | Unit |
|
||||
| - | - | - |
|
||||
| `PENDING_DEPOSITS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending deposits |
|
||||
| Name | Value | Unit |
|
||||
| ----------------------------------- | ------------------------------- | --------------------------- |
|
||||
| `PENDING_DEPOSITS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending deposits |
|
||||
| `PENDING_PARTIAL_WITHDRAWALS_LIMIT` | `uint64(2**27)` (= 134,217,728) | pending partial withdrawals |
|
||||
| `PENDING_CONSOLIDATIONS_LIMIT` | `uint64(2**18)` (= 262,144) | pending consolidations |
|
||||
| `PENDING_CONSOLIDATIONS_LIMIT` | `uint64(2**18)` (= 262,144) | pending consolidations |
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| -------------------------------- | ------------ |
|
||||
| `MAX_ATTESTER_SLASHINGS_ELECTRA` | `2**0` (= 1) |
|
||||
| `MAX_ATTESTATIONS_ELECTRA` | `2**3` (= 8) |
|
||||
| `MAX_ATTESTATIONS_ELECTRA` | `2**3` (= 8) |
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MAX_DEPOSIT_REQUESTS_PER_PAYLOAD` | `uint64(2**13)` (= 8,192) | *[New in Electra:EIP6110]* Maximum number of execution layer deposit requests in each payload |
|
||||
| `MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD` | `uint64(2**4)` (= 16)| *[New in Electra:EIP7002]* Maximum number of execution layer withdrawal requests in each payload |
|
||||
| `MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD` | `uint64(2**1)` (= 2) | *[New in Electra:EIP7251]* Maximum number of execution layer consolidation requests in each payload |
|
||||
| Name | Value | Description |
|
||||
| ---------------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `MAX_DEPOSIT_REQUESTS_PER_PAYLOAD` | `uint64(2**13)` (= 8,192) | *[New in Electra:EIP6110]* Maximum number of execution layer deposit requests in each payload |
|
||||
| `MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD` | `uint64(2**4)` (= 16) | *[New in Electra:EIP7002]* Maximum number of execution layer withdrawal requests in each payload |
|
||||
| `MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD` | `uint64(2**1)` (= 2) | *[New in Electra:EIP7251]* Maximum number of execution layer consolidation requests in each payload |
|
||||
|
||||
### Withdrawals processing
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP` | `uint64(2**3)` (= 8)| *[New in Electra:EIP7002]* Maximum number of pending partial withdrawals to process per payload |
|
||||
| Name | Value | Description |
|
||||
| -------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP` | `uint64(2**3)` (= 8) | *[New in Electra:EIP7002]* Maximum number of pending partial withdrawals to process per payload |
|
||||
|
||||
### Pending deposits processing
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MAX_PENDING_DEPOSITS_PER_EPOCH` | `uint64(2**4)` (= 16)| *[New in Electra:EIP6110]* Maximum number of pending deposits to process per epoch |
|
||||
| Name | Value | Description |
|
||||
| -------------------------------- | --------------------- | ---------------------------------------------------------------------------------- |
|
||||
| `MAX_PENDING_DEPOSITS_PER_EPOCH` | `uint64(2**4)` (= 16) | *[New in Electra:EIP6110]* Maximum number of pending deposits to process per epoch |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| ----------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| `MAX_BLOBS_PER_BLOCK_ELECTRA` | `uint64(9)` | *[New in Electra:EIP7691]* Maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` |
|
||||
|
||||
### Validator cycle
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA` | `Gwei(2**7 * 10**9)` (= 128,000,000,000) | # Equivalent to 4 32 ETH validators
|
||||
| Name | Value |
|
||||
| ------------------------------------------- | ---------------------------------------- |
|
||||
| `MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA` | `Gwei(2**7 * 10**9)` (= 128,000,000,000) |
|
||||
| `MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT` | `Gwei(2**8 * 10**9)` (= 256,000,000,000) |
|
||||
|
||||
## Containers
|
||||
@@ -880,6 +875,7 @@ def apply_pending_deposit(state: BeaconState, deposit: PendingDeposit) -> None:
|
||||
#### New `process_pending_deposits`
|
||||
|
||||
Iterating over `pending_deposits` queue this function runs the following checks before applying pending deposit:
|
||||
|
||||
1. All Eth1 bridge deposits are processed before the first deposit request gets processed.
|
||||
2. Deposit position in the queue is finalized.
|
||||
3. Deposit does not exceed the `MAX_PENDING_DEPOSITS_PER_EPOCH` limit.
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -17,8 +13,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -28,10 +23,10 @@ This document describes the process of the Electra upgrade.
|
||||
|
||||
Warning: this configuration is not definitive.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `ELECTRA_FORK_VERSION` | `Version('0x05000000')` |
|
||||
| `ELECTRA_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
| Name | Value |
|
||||
| ---------------------- | ------------------------------------- |
|
||||
| `ELECTRA_FORK_VERSION` | `Version('0x05000000')` |
|
||||
| `ELECTRA_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
@@ -14,8 +10,7 @@
|
||||
- [Upgrading light client data](#upgrading-light-client-data)
|
||||
- [Upgrading the store](#upgrading-the-store)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Networking](#networking)
|
||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||
@@ -21,8 +17,7 @@
|
||||
- [GetLightClientFinalityUpdate](#getlightclientfinalityupdate)
|
||||
- [GetLightClientOptimisticUpdate](#getlightclientoptimisticupdate)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Networking
|
||||
|
||||
@@ -36,10 +31,10 @@ The [Deneb light client networking specification](../../deneb/light-client/p2p-i
|
||||
|
||||
###### `light_client_finality_update`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
|--------------------------------------------------------|-------------------------------------|
|
||||
| ------------------------------------------------------ | ----------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientFinalityUpdate` |
|
||||
@@ -48,10 +43,10 @@ The [Deneb light client networking specification](../../deneb/light-client/p2p-i
|
||||
|
||||
###### `light_client_optimistic_update`
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Message SSZ type |
|
||||
|--------------------------------------------------------|---------------------------------------|
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientOptimisticUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientOptimisticUpdate` |
|
||||
@@ -64,34 +59,34 @@ The [Deneb light client networking specification](../../deneb/light-client/p2p-i
|
||||
|
||||
##### GetLightClientBootstrap
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
|--------------------------------------------------------|------------------------------------|
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientBootstrap` |
|
||||
| `DENEB_FORK_VERSION` | `deneb.LightClientBootstrap` |
|
||||
| `ELECTRA_FORK_VERSION` and later | `electra.LightClientBootstrap` |
|
||||
| `fork_version` | Response SSZ type |
|
||||
| ------------------------------------------------------ | ------------------------------ |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientBootstrap` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientBootstrap` |
|
||||
| `DENEB_FORK_VERSION` | `deneb.LightClientBootstrap` |
|
||||
| `ELECTRA_FORK_VERSION` and later | `electra.LightClientBootstrap` |
|
||||
|
||||
##### LightClientUpdatesByRange
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
|--------------------------------------------------------|----------------------------------|
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientUpdate` |
|
||||
| `DENEB_FORK_VERSION` | `deneb.LightClientUpdate` |
|
||||
| `ELECTRA_FORK_VERSION` and later | `electra.LightClientUpdate` |
|
||||
| `fork_version` | Response chunk SSZ type |
|
||||
| ------------------------------------------------------ | --------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientUpdate` |
|
||||
| `DENEB_FORK_VERSION` | `deneb.LightClientUpdate` |
|
||||
| `ELECTRA_FORK_VERSION` and later | `electra.LightClientUpdate` |
|
||||
|
||||
##### GetLightClientFinalityUpdate
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
|--------------------------------------------------------|-------------------------------------|
|
||||
| ------------------------------------------------------ | ----------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientFinalityUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientFinalityUpdate` |
|
||||
@@ -100,10 +95,10 @@ The [Deneb light client networking specification](../../deneb/light-client/p2p-i
|
||||
|
||||
##### GetLightClientOptimisticUpdate
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Response SSZ type |
|
||||
|--------------------------------------------------------|---------------------------------------|
|
||||
| ------------------------------------------------------ | ------------------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | n/a |
|
||||
| `ALTAIR_FORK_VERSION` through `BELLATRIX_FORK_VERSION` | `altair.LightClientOptimisticUpdate` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.LightClientOptimisticUpdate` |
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Custom types](#custom-types)
|
||||
@@ -19,23 +15,23 @@
|
||||
- [Modified `next_sync_committee_gindex_at_slot`](#modified-next_sync_committee_gindex_at_slot)
|
||||
- [Modified `get_lc_execution_root`](#modified-get_lc_execution_root)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
This upgrade updates light client data to include the Electra changes to the [`ExecutionPayload`](../beacon-chain.md) structure and to the generalized indices of surrounding containers. It extends the [Deneb Light Client specifications](../../deneb/light-client/sync-protocol.md). The [fork document](./fork.md) explains how to upgrade existing Deneb based deployments to Electra.
|
||||
|
||||
Additional documents describes the impact of the upgrade on certain roles:
|
||||
|
||||
- [Networking](./p2p-interface.md)
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `FinalityBranch` | `Vector[Bytes32, floorlog2(FINALIZED_ROOT_GINDEX_ELECTRA)]` | Merkle branch of `finalized_checkpoint.root` within `BeaconState` |
|
||||
| `CurrentSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(CURRENT_SYNC_COMMITTEE_GINDEX_ELECTRA)]` | Merkle branch of `current_sync_committee` within `BeaconState` |
|
||||
| `NextSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(NEXT_SYNC_COMMITTEE_GINDEX_ELECTRA)]` | Merkle branch of `next_sync_committee` within `BeaconState` |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ---------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `FinalityBranch` | `Vector[Bytes32, floorlog2(FINALIZED_ROOT_GINDEX_ELECTRA)]` | Merkle branch of `finalized_checkpoint.root` within `BeaconState` |
|
||||
| `CurrentSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(CURRENT_SYNC_COMMITTEE_GINDEX_ELECTRA)]` | Merkle branch of `current_sync_committee` within `BeaconState` |
|
||||
| `NextSyncCommitteeBranch` | `Vector[Bytes32, floorlog2(NEXT_SYNC_COMMITTEE_GINDEX_ELECTRA)]` | Merkle branch of `next_sync_committee` within `BeaconState` |
|
||||
|
||||
## Constants
|
||||
|
||||
@@ -43,19 +39,19 @@ Additional documents describes the impact of the upgrade on certain roles:
|
||||
|
||||
Existing `GeneralizedIndex` constants are frozen at their [Altair](../../altair/light-client/sync-protocol.md#constants) values.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `FINALIZED_ROOT_GINDEX` | `get_generalized_index(altair.BeaconState, 'finalized_checkpoint', 'root')` (= 105) |
|
||||
| `CURRENT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(altair.BeaconState, 'current_sync_committee')` (= 54) |
|
||||
| `NEXT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(altair.BeaconState, 'next_sync_committee')` (= 55) |
|
||||
| Name | Value |
|
||||
| ------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `FINALIZED_ROOT_GINDEX` | `get_generalized_index(altair.BeaconState, 'finalized_checkpoint', 'root')` (= 105) |
|
||||
| `CURRENT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(altair.BeaconState, 'current_sync_committee')` (= 54) |
|
||||
| `NEXT_SYNC_COMMITTEE_GINDEX` | `get_generalized_index(altair.BeaconState, 'next_sync_committee')` (= 55) |
|
||||
|
||||
### New constants
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `FINALIZED_ROOT_GINDEX_ELECTRA` | `get_generalized_index(BeaconState, 'finalized_checkpoint', 'root')` (= 169) |
|
||||
| `CURRENT_SYNC_COMMITTEE_GINDEX_ELECTRA` | `get_generalized_index(BeaconState, 'current_sync_committee')` (= 86) |
|
||||
| `NEXT_SYNC_COMMITTEE_GINDEX_ELECTRA` | `get_generalized_index(BeaconState, 'next_sync_committee')` (= 87) |
|
||||
| Name | Value |
|
||||
| --------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `FINALIZED_ROOT_GINDEX_ELECTRA` | `get_generalized_index(BeaconState, 'finalized_checkpoint', 'root')` (= 169) |
|
||||
| `CURRENT_SYNC_COMMITTEE_GINDEX_ELECTRA` | `get_generalized_index(BeaconState, 'current_sync_committee')` (= 86) |
|
||||
| `NEXT_SYNC_COMMITTEE_GINDEX_ELECTRA` | `get_generalized_index(BeaconState, 'next_sync_committee')` (= 87) |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Electra](#modifications-in-electra)
|
||||
@@ -26,8 +22,7 @@
|
||||
- [BlobSidecarsByRange v1](#blobsidecarsbyrange-v1)
|
||||
- [BlobSidecarsByRoot v1](#blobsidecarsbyroot-v1)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -42,7 +37,7 @@ The specification of these changes continues in the same format as the network s
|
||||
*[New in Electra:EIP7691]*
|
||||
|
||||
| Name | Value | Description |
|
||||
|-------------------------------------|----------------------------------------------------------|-------------------------------------------------------------------|
|
||||
| ----------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `MAX_REQUEST_BLOB_SIDECARS_ELECTRA` | `MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA` | Maximum number of blob sidecars in a single request |
|
||||
| `BLOB_SIDECAR_SUBNET_COUNT_ELECTRA` | `9` | The number of blob sidecar subnets used in the gossipsub protocol |
|
||||
|
||||
@@ -81,8 +76,8 @@ The following convenience variables are re-defined
|
||||
|
||||
The following validations are added:
|
||||
|
||||
* [REJECT] `len(committee_indices) == 1`, where `committee_indices = get_committee_indices(aggregate)`.
|
||||
* [REJECT] `aggregate.data.index == 0`
|
||||
- [REJECT] `len(committee_indices) == 1`, where `committee_indices = get_committee_indices(aggregate)`.
|
||||
- [REJECT] `aggregate.data.index == 0`
|
||||
|
||||
###### `blob_sidecar_{subnet_id}`
|
||||
|
||||
@@ -90,7 +85,7 @@ The following validations are added:
|
||||
|
||||
The existing validations all apply as given from previous forks, with the following exceptions:
|
||||
|
||||
* Uses of `MAX_BLOBS_PER_BLOCK` in existing validations are replaced with `MAX_BLOBS_PER_BLOCK_ELECTRA`.
|
||||
- Uses of `MAX_BLOBS_PER_BLOCK` in existing validations are replaced with `MAX_BLOBS_PER_BLOCK_ELECTRA`.
|
||||
|
||||
##### Attestation subnets
|
||||
|
||||
@@ -127,10 +122,10 @@ The Electra fork-digest is introduced to the `context` enum to specify Electra b
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
@@ -144,10 +139,10 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -33,8 +29,7 @@
|
||||
- [Attestation aggregation](#attestation-aggregation)
|
||||
- [Construct aggregate](#construct-aggregate)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -16,8 +12,7 @@
|
||||
- [Execution payload](#execution-payload)
|
||||
- [Modified `process_execution_payload`](#modified-process_execution_payload)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -27,8 +22,8 @@
|
||||
|
||||
### Execution
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| -------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |
|
||||
| `MAX_BLOBS_PER_BLOCK_FULU` | `uint64(12)` | *[New in Fulu:EIP7594]* Maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` |
|
||||
|
||||
## Beacon chain state transition function
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Constants](#constants)
|
||||
- [Misc](#misc)
|
||||
@@ -35,8 +31,7 @@
|
||||
- [Why don't we rotate custody over time?](#why-dont-we-rotate-custody-over-time)
|
||||
- [Does having a lot of column subnets make the network unstable?](#does-having-a-lot-of-column-subnets-make-the-network-unstable)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Constants
|
||||
|
||||
@@ -44,33 +39,33 @@ The following values are (non-configurable) constants used throughout the specif
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ------------- | --------------------- |
|
||||
| `UINT256_MAX` | `uint256(2**256 - 1)` |
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `RowIndex` | `uint64` | Row identifier in the matrix of cells |
|
||||
| `ColumnIndex` | `uint64` | Column identifier in the matrix of cells |
|
||||
| `CustodyIndex` | `uint64` | Custody group identifier in the set of custody groups |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| -------------- | -------------- | ----------------------------------------------------- |
|
||||
| `RowIndex` | `uint64` | Row identifier in the matrix of cells |
|
||||
| `ColumnIndex` | `uint64` | Column identifier in the matrix of cells |
|
||||
| `CustodyIndex` | `uint64` | Custody group identifier in the set of custody groups |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Data size
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| Name | Value | Description |
|
||||
| ------------------- | ------------------------------------ | --------------------------------------------- |
|
||||
| `NUMBER_OF_COLUMNS` | `uint64(CELLS_PER_EXT_BLOB)` (= 128) | Number of columns in the extended data matrix |
|
||||
|
||||
### Custody setting
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `SAMPLES_PER_SLOT` | `8` | Number of `DataColumnSidecar` random samples a node queries per slot |
|
||||
| `NUMBER_OF_CUSTODY_GROUPS` | `128` | Number of custody groups available for nodes to custody |
|
||||
| `CUSTODY_REQUIREMENT` | `4` | Minimum number of custody groups an honest node custodies and serves samples from |
|
||||
| Name | Value | Description |
|
||||
| -------------------------- | ----- | --------------------------------------------------------------------------------- |
|
||||
| `SAMPLES_PER_SLOT` | `8` | Number of `DataColumnSidecar` random samples a node queries per slot |
|
||||
| `NUMBER_OF_CUSTODY_GROUPS` | `128` | Number of custody groups available for nodes to custody |
|
||||
| `CUSTODY_REQUIREMENT` | `4` | Minimum number of custody groups an honest node custodies and serves samples from |
|
||||
|
||||
### Containers
|
||||
|
||||
@@ -233,7 +228,7 @@ In the one-dimension construction, a node samples the peers by requesting the wh
|
||||
|
||||
The potential benefits of having row custody could include:
|
||||
|
||||
1. Allow for more "natural" distribution of data to consumers -- e.g., roll-ups -- but honestly, they won't know a priori which row their blob is going to be included in in the block, so they would either need to listen to all rows or download a particular row after seeing the block. The former looks just like listening to column [0, N) and the latter is req/resp instead of gossiping.
|
||||
1. Allow for more "natural" distribution of data to consumers -- e.g., roll-ups -- but honestly, they won't know a priori which row their blob is going to be included in in the block, so they would either need to listen to all rows or download a particular row after seeing the block. The former looks just like listening to column \[0, N) and the latter is req/resp instead of gossiping.
|
||||
2. Help with some sort of distributed reconstruction. Those with full rows can compute extensions and seed missing samples to the network. This would either need to be able to send individual points on the gossip or would need some sort of req/resp faculty, potentially similar to an `IHAVEPOINTBITFIELD` and `IWANTSAMPLE`.
|
||||
|
||||
However, for simplicity, we don't assign row custody assignments to nodes in the current design.
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helpers](#helpers)
|
||||
@@ -14,8 +10,7 @@
|
||||
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
|
||||
- [Modified `on_block`](#modified-on_block)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Configuration](#configuration)
|
||||
@@ -17,8 +13,7 @@
|
||||
- [Fork trigger](#fork-trigger)
|
||||
- [Upgrading the state](#upgrading-the-state)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -28,10 +23,10 @@ This document describes the process of Fulu upgrade.
|
||||
|
||||
Warning: this configuration is not definitive.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `FULU_FORK_VERSION` | `Version('0x06000000')` |
|
||||
| `FULU_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
| Name | Value |
|
||||
| ------------------- | ------------------------------------- |
|
||||
| `FULU_FORK_VERSION` | `Version('0x06000000')` |
|
||||
| `FULU_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Modifications in Fulu](#modifications-in-fulu)
|
||||
@@ -15,10 +11,10 @@
|
||||
- [Containers](#containers)
|
||||
- [`DataColumnIdentifier`](#datacolumnidentifier)
|
||||
- [Helpers](#helpers)
|
||||
- [`verify_data_column_sidecar`](#verify_data_column_sidecar)
|
||||
- [`verify_data_column_sidecar_kzg_proofs`](#verify_data_column_sidecar_kzg_proofs)
|
||||
- [`verify_data_column_sidecar_inclusion_proof`](#verify_data_column_sidecar_inclusion_proof)
|
||||
- [`compute_subnet_for_data_column_sidecar`](#compute_subnet_for_data_column_sidecar)
|
||||
- [`verify_data_column_sidecar`](#verify_data_column_sidecar)
|
||||
- [`verify_data_column_sidecar_kzg_proofs`](#verify_data_column_sidecar_kzg_proofs)
|
||||
- [`verify_data_column_sidecar_inclusion_proof`](#verify_data_column_sidecar_inclusion_proof)
|
||||
- [`compute_subnet_for_data_column_sidecar`](#compute_subnet_for_data_column_sidecar)
|
||||
- [MetaData](#metadata)
|
||||
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
|
||||
- [Topics and messages](#topics-and-messages)
|
||||
@@ -37,8 +33,7 @@
|
||||
- [ENR structure](#enr-structure)
|
||||
- [Custody group count](#custody-group-count)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -51,18 +46,18 @@ The specification of these changes continues in the same format as the network s
|
||||
### Preset
|
||||
|
||||
| Name | Value | Description |
|
||||
|-----------------------------------------|-------------------------------------------------------------------------------------------|-------------------------------------------------------------------|
|
||||
| --------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH` | `uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments')))` (= 4) | <!-- predefined --> Merkle proof index for `blob_kzg_commitments` |
|
||||
|
||||
### Configuration
|
||||
|
||||
*[New in Fulu:EIP7594]*
|
||||
|
||||
| Name | Value | Description |
|
||||
|------------------------------------------------|-------------------------------------------------------|---------------------------------------------------------------------------|
|
||||
| `DATA_COLUMN_SIDECAR_SUBNET_COUNT` | `128` | The number of data column sidecar subnets used in the gossipsub protocol |
|
||||
| `MAX_REQUEST_DATA_COLUMN_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS` | Maximum number of data column sidecars in a single request |
|
||||
| `MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve data column sidecars |
|
||||
| Name | Value | Description |
|
||||
| ---------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| `DATA_COLUMN_SIDECAR_SUBNET_COUNT` | `128` | The number of data column sidecar subnets used in the gossipsub protocol |
|
||||
| `MAX_REQUEST_DATA_COLUMN_SIDECARS` | `MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS` | Maximum number of data column sidecars in a single request |
|
||||
| `MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS` | `2**12` (= 4096 epochs, ~18 days) | The minimum epoch range over which a node must serve data column sidecars |
|
||||
|
||||
### Containers
|
||||
|
||||
@@ -213,8 +208,8 @@ Implementers are encouraged to leverage this method to increase the likelihood o
|
||||
|
||||
When clients use the local execution layer to retrieve blob and compute data columns, they MUST behave as if the imported `data_column_sidecar` had been received via gossip. In particular, clients MUST:
|
||||
|
||||
* Publish the corresponding `data_column_sidecar` on the `data_column_sidecar_{subnet_id}` topic **if and only if** they are **subscribed** to it, either due to custody requirements or additional sampling.
|
||||
* Update gossip rule related data structures (i.e. update the anti-equivocation cache).
|
||||
- Publish the corresponding `data_column_sidecar` on the `data_column_sidecar_{subnet_id}` topic **if and only if** they are **subscribed** to it, either due to custody requirements or additional sampling.
|
||||
- Update gossip rule related data structures (i.e. update the anti-equivocation cache).
|
||||
|
||||
### The Req/Resp domain
|
||||
|
||||
@@ -226,10 +221,10 @@ When clients use the local execution layer to retrieve blob and compute data col
|
||||
|
||||
The `<context-bytes>` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|---------------------|--------------------------|
|
||||
| ------------------- | ------------------------ |
|
||||
| `FULU_FORK_VERSION` | `fulu.DataColumnSidecar` |
|
||||
|
||||
Request Content:
|
||||
@@ -309,10 +304,10 @@ After the initial data column sidecar, clients MAY stop in the process of respon
|
||||
|
||||
The `<context-bytes>` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|---------------------|--------------------------|
|
||||
| ------------------- | ------------------------ |
|
||||
| `FULU_FORK_VERSION` | `fulu.DataColumnSidecar` |
|
||||
|
||||
Request Content:
|
||||
@@ -375,6 +370,6 @@ Requests the MetaData of a peer, using the new `MetaData` definition given above
|
||||
|
||||
A new field is added to the ENR under the key `cgc` to facilitate custody data column discovery.
|
||||
|
||||
| Key | Value |
|
||||
|--------|------------------------------------------|
|
||||
| `cgc` | Custody group count, `uint64` big endian integer with no leading zero bytes (`0` is encoded as empty byte string) |
|
||||
| Key | Value |
|
||||
| ----- | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| `cgc` | Custody group count, `uint64` big endian integer with no leading zero bytes (`0` is encoded as empty byte string) |
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
@@ -18,8 +14,7 @@
|
||||
- [Peer scoring](#peer-scoring)
|
||||
- [DAS providers](#das-providers)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -89,9 +84,9 @@ Alternatively, a node MAY use a method that selects more than `SAMPLES_PER_SLOT`
|
||||
|
||||
For reference, the table below shows the number of samples and the number of allowed missing columns assuming `NUMBER_OF_COLUMNS = 128` and `SAMPLES_PER_SLOT = 16`.
|
||||
|
||||
| Allowed missing | 0| 1| 2| 3| 4| 5| 6| 7| 8|
|
||||
|-----------------|--|--|--|--|--|--|--|--|--|
|
||||
| Sample count |16|20|24|27|29|32|35|37|40|
|
||||
| Allowed missing | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
| --------------- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| Sample count | 16 | 20 | 24 | 27 | 29 | 32 | 35 | 37 | 40 |
|
||||
|
||||
### Sample queries
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
*Note*: This document is a work-in-progress for researchers and implementers.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Public Methods](#public-methods)
|
||||
@@ -49,8 +45,7 @@
|
||||
- [`recover_polynomialcoeff`](#recover_polynomialcoeff)
|
||||
- [`recover_cells_and_kzg_proofs`](#recover_cells_and_kzg_proofs)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -70,19 +65,19 @@ The following is a list of the public methods:
|
||||
|
||||
## Custom types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `Cell` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_CELL]` | The unit of blob data that can come with its own KZG proof |
|
||||
| `CellIndex` | `uint64` | Validation: `x < CELLS_PER_EXT_BLOB` |
|
||||
| `CommitmentIndex` | `uint64` | The type which represents the index of an element in the list of commitments |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ----------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `Cell` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_CELL]` | The unit of blob data that can come with its own KZG proof |
|
||||
| `CellIndex` | `uint64` | Validation: `x < CELLS_PER_EXT_BLOB` |
|
||||
| `CommitmentIndex` | `uint64` | The type which represents the index of an element in the list of commitments |
|
||||
|
||||
## Cryptographic types
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| [`PolynomialCoeff`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/eip7594.py#L20-L24) | `List[BLSFieldElement, FIELD_ELEMENTS_PER_EXT_BLOB]` | <!-- predefined-type --> A polynomial in coefficient form |
|
||||
| [`Coset`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/eip7594.py#L27-L33) | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_CELL]` | <!-- predefined-type --> The evaluation domain of a cell |
|
||||
| [`CosetEvals`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/eip7594.py#L36-L42) | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_CELL]` | <!-- predefined-type --> A cell's evaluations over its coset |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| [`PolynomialCoeff`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/eip7594.py#L20-L24) | `List[BLSFieldElement, FIELD_ELEMENTS_PER_EXT_BLOB]` | <!-- predefined-type --> A polynomial in coefficient form |
|
||||
| [`Coset`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/eip7594.py#L27-L33) | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_CELL]` | <!-- predefined-type --> The evaluation domain of a cell |
|
||||
| [`CosetEvals`](https://github.com/ethereum/consensus-specs/blob/36a5719b78523c057065515c8f8fcaeba75d065b/pysetup/spec_builders/eip7594.py#L36-L42) | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_CELL]` | <!-- predefined-type --> A cell's evaluations over its coset |
|
||||
|
||||
## Preset
|
||||
|
||||
@@ -90,13 +85,13 @@ The following is a list of the public methods:
|
||||
|
||||
Cells are the smallest unit of blob data that can come with their own KZG proofs. Samples can be constructed from one or several cells (e.g. an individual cell or line).
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `FIELD_ELEMENTS_PER_EXT_BLOB` | `2 * FIELD_ELEMENTS_PER_BLOB` | Number of field elements in a Reed-Solomon extended blob |
|
||||
| `FIELD_ELEMENTS_PER_CELL` | `uint64(64)` | Number of field elements in a cell |
|
||||
| `BYTES_PER_CELL` | `FIELD_ELEMENTS_PER_CELL * BYTES_PER_FIELD_ELEMENT` | The number of bytes in a cell |
|
||||
| `CELLS_PER_EXT_BLOB` | `FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL` | The number of cells in an extended blob |
|
||||
| `RANDOM_CHALLENGE_KZG_CELL_BATCH_DOMAIN` | `b'RCKZGCBATCH__V1_'` |
|
||||
| Name | Value | Description |
|
||||
| ---------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
|
||||
| `FIELD_ELEMENTS_PER_EXT_BLOB` | `2 * FIELD_ELEMENTS_PER_BLOB` | Number of field elements in a Reed-Solomon extended blob |
|
||||
| `FIELD_ELEMENTS_PER_CELL` | `uint64(64)` | Number of field elements in a cell |
|
||||
| `BYTES_PER_CELL` | `FIELD_ELEMENTS_PER_CELL * BYTES_PER_FIELD_ELEMENT` | The number of bytes in a cell |
|
||||
| `CELLS_PER_EXT_BLOB` | `FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL` | The number of cells in an extended blob |
|
||||
| `RANDOM_CHALLENGE_KZG_CELL_BATCH_DOMAIN` | `b'RCKZGCBATCH__V1_'` | |
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Fulu -- Honest Validator
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -26,8 +22,7 @@
|
||||
- [Sidecar publishing](#sidecar-publishing)
|
||||
- [Sidecar retention](#sidecar-retention)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -47,10 +42,10 @@ document and used throughout.
|
||||
|
||||
### Custody setting
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `VALIDATOR_CUSTODY_REQUIREMENT` | `8` | Minimum number of custody groups an honest node with validators attached custodies and serves samples from |
|
||||
| `BALANCE_PER_ADDITIONAL_CUSTODY_GROUP` | `Gwei(32 * 10**9)` | Effective balance increment corresponding to one additional group to custody |
|
||||
| Name | Value | Description |
|
||||
| -------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `VALIDATOR_CUSTODY_REQUIREMENT` | `8` | Minimum number of custody groups an honest node with validators attached custodies and serves samples from |
|
||||
| `BALANCE_PER_ADDITIONAL_CUSTODY_GROUP` | `Gwei(32 * 10**9)` | Effective balance increment corresponding to one additional group to custody |
|
||||
|
||||
## Helpers
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Phase 0 -- The Beacon Chain
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Notation](#notation)
|
||||
@@ -137,8 +133,7 @@
|
||||
- [Deposits](#deposits)
|
||||
- [Voluntary exits](#voluntary-exits)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -155,21 +150,21 @@ Code snippets appearing in `this style` are to be interpreted as Python 3 code.
|
||||
|
||||
We define the following Python custom types for type hinting and readability:
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `Slot` | `uint64` | a slot number |
|
||||
| `Epoch` | `uint64` | an epoch number |
|
||||
| `CommitteeIndex` | `uint64` | a committee index at a slot |
|
||||
| `ValidatorIndex` | `uint64` | a validator registry index |
|
||||
| `Gwei` | `uint64` | an amount in Gwei |
|
||||
| `Root` | `Bytes32` | a Merkle root |
|
||||
| `Hash32` | `Bytes32` | a 256-bit hash |
|
||||
| `Version` | `Bytes4` | a fork version number |
|
||||
| `DomainType` | `Bytes4` | a domain type |
|
||||
| `ForkDigest` | `Bytes4` | a digest of the current fork data |
|
||||
| `Domain` | `Bytes32` | a signature domain |
|
||||
| `BLSPubkey` | `Bytes48` | a BLS12-381 public key |
|
||||
| `BLSSignature` | `Bytes96` | a BLS12-381 signature |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ---------------- | -------------- | --------------------------------- |
|
||||
| `Slot` | `uint64` | a slot number |
|
||||
| `Epoch` | `uint64` | an epoch number |
|
||||
| `CommitteeIndex` | `uint64` | a committee index at a slot |
|
||||
| `ValidatorIndex` | `uint64` | a validator registry index |
|
||||
| `Gwei` | `uint64` | an amount in Gwei |
|
||||
| `Root` | `Bytes32` | a Merkle root |
|
||||
| `Hash32` | `Bytes32` | a 256-bit hash |
|
||||
| `Version` | `Bytes4` | a fork version number |
|
||||
| `DomainType` | `Bytes4` | a domain type |
|
||||
| `ForkDigest` | `Bytes4` | a digest of the current fork data |
|
||||
| `Domain` | `Bytes32` | a signature domain |
|
||||
| `BLSPubkey` | `Bytes48` | a BLS12-381 public key |
|
||||
| `BLSSignature` | `Bytes96` | a BLS12-381 signature |
|
||||
|
||||
## Constants
|
||||
|
||||
@@ -177,29 +172,29 @@ The following values are (non-configurable) constants used throughout the specif
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `UINT64_MAX` | `uint64(2**64 - 1)` |
|
||||
| `UINT64_MAX_SQRT` | `uint64(4294967295)` |
|
||||
| `GENESIS_SLOT` | `Slot(0)` |
|
||||
| `GENESIS_EPOCH` | `Epoch(0)` |
|
||||
| `FAR_FUTURE_EPOCH` | `Epoch(2**64 - 1)` |
|
||||
| `BASE_REWARDS_PER_EPOCH` | `uint64(4)` |
|
||||
| Name | Value |
|
||||
| ----------------------------- | --------------------- |
|
||||
| `UINT64_MAX` | `uint64(2**64 - 1)` |
|
||||
| `UINT64_MAX_SQRT` | `uint64(4294967295)` |
|
||||
| `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'` |
|
||||
| `JUSTIFICATION_BITS_LENGTH` | `uint64(4)` |
|
||||
| `ENDIANNESS` | `'little'` |
|
||||
|
||||
### Withdrawal prefixes
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `BLS_WITHDRAWAL_PREFIX` | `Bytes1('0x00')` |
|
||||
| Name | Value |
|
||||
| -------------------------------- | ---------------- |
|
||||
| `BLS_WITHDRAWAL_PREFIX` | `Bytes1('0x00')` |
|
||||
| `ETH1_ADDRESS_WITHDRAWAL_PREFIX` | `Bytes1('0x01')` |
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ---------------------------- | -------------------------- |
|
||||
| `DOMAIN_BEACON_PROPOSER` | `DomainType('0x00000000')` |
|
||||
| `DOMAIN_BEACON_ATTESTER` | `DomainType('0x01000000')` |
|
||||
| `DOMAIN_RANDAO` | `DomainType('0x02000000')` |
|
||||
@@ -219,57 +214,57 @@ Additional preset configurations can be found in the [`configs`](../../configs)
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_COMMITTEES_PER_SLOT` | `uint64(2**6)` (= 64) |
|
||||
| `TARGET_COMMITTEE_SIZE` | `uint64(2**7)` (= 128) |
|
||||
| `MAX_VALIDATORS_PER_COMMITTEE` | `uint64(2**11)` (= 2,048) |
|
||||
| `SHUFFLE_ROUND_COUNT` | `uint64(90)` |
|
||||
| `HYSTERESIS_QUOTIENT` | `uint64(4)` |
|
||||
| `HYSTERESIS_DOWNWARD_MULTIPLIER` | `uint64(1)` |
|
||||
| `HYSTERESIS_UPWARD_MULTIPLIER` | `uint64(5)` |
|
||||
| Name | Value |
|
||||
| -------------------------------- | ------------------------- |
|
||||
| `MAX_COMMITTEES_PER_SLOT` | `uint64(2**6)` (= 64) |
|
||||
| `TARGET_COMMITTEE_SIZE` | `uint64(2**7)` (= 128) |
|
||||
| `MAX_VALIDATORS_PER_COMMITTEE` | `uint64(2**11)` (= 2,048) |
|
||||
| `SHUFFLE_ROUND_COUNT` | `uint64(90)` |
|
||||
| `HYSTERESIS_QUOTIENT` | `uint64(4)` |
|
||||
| `HYSTERESIS_DOWNWARD_MULTIPLIER` | `uint64(1)` |
|
||||
| `HYSTERESIS_UPWARD_MULTIPLIER` | `uint64(5)` |
|
||||
|
||||
- For the safety of committees, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](http://web.archive.org/web/20190504131341/https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.)
|
||||
|
||||
### Gwei values
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MIN_DEPOSIT_AMOUNT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) |
|
||||
| `MAX_EFFECTIVE_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) |
|
||||
| `EFFECTIVE_BALANCE_INCREMENT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) |
|
||||
| Name | Value |
|
||||
| ----------------------------- | --------------------------------------- |
|
||||
| `MIN_DEPOSIT_AMOUNT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) |
|
||||
| `MAX_EFFECTIVE_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) |
|
||||
| `EFFECTIVE_BALANCE_INCREMENT` | `Gwei(2**0 * 10**9)` (= 1,000,000,000) |
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| `MIN_ATTESTATION_INCLUSION_DELAY` | `uint64(2**0)` (= 1) | slots | 12 seconds |
|
||||
| `SLOTS_PER_EPOCH` | `uint64(2**5)` (= 32) | slots | 6.4 minutes |
|
||||
| `MIN_SEED_LOOKAHEAD` | `uint64(2**0)` (= 1) | epochs | 6.4 minutes |
|
||||
| `MAX_SEED_LOOKAHEAD` | `uint64(2**2)` (= 4) | epochs | 25.6 minutes |
|
||||
| `MIN_EPOCHS_TO_INACTIVITY_PENALTY` | `uint64(2**2)` (= 4) | epochs | 25.6 minutes |
|
||||
| `EPOCHS_PER_ETH1_VOTING_PERIOD` | `uint64(2**6)` (= 64) | epochs | ~6.8 hours |
|
||||
| `SLOTS_PER_HISTORICAL_ROOT` | `uint64(2**13)` (= 8,192) | slots | ~27 hours |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ---------------------------------- | ------------------------- | :----: | :----------: |
|
||||
| `MIN_ATTESTATION_INCLUSION_DELAY` | `uint64(2**0)` (= 1) | slots | 12 seconds |
|
||||
| `SLOTS_PER_EPOCH` | `uint64(2**5)` (= 32) | slots | 6.4 minutes |
|
||||
| `MIN_SEED_LOOKAHEAD` | `uint64(2**0)` (= 1) | epochs | 6.4 minutes |
|
||||
| `MAX_SEED_LOOKAHEAD` | `uint64(2**2)` (= 4) | epochs | 25.6 minutes |
|
||||
| `MIN_EPOCHS_TO_INACTIVITY_PENALTY` | `uint64(2**2)` (= 4) | epochs | 25.6 minutes |
|
||||
| `EPOCHS_PER_ETH1_VOTING_PERIOD` | `uint64(2**6)` (= 64) | epochs | ~6.8 hours |
|
||||
| `SLOTS_PER_HISTORICAL_ROOT` | `uint64(2**13)` (= 8,192) | slots | ~27 hours |
|
||||
|
||||
### State list lengths
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| `EPOCHS_PER_HISTORICAL_VECTOR` | `uint64(2**16)` (= 65,536) | epochs | ~0.8 years |
|
||||
| `EPOCHS_PER_SLASHINGS_VECTOR` | `uint64(2**13)` (= 8,192) | epochs | ~36 days |
|
||||
| `HISTORICAL_ROOTS_LIMIT` | `uint64(2**24)` (= 16,777,216) | historical roots | ~52,262 years |
|
||||
| `VALIDATOR_REGISTRY_LIMIT` | `uint64(2**40)` (= 1,099,511,627,776) | validators |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ------------------------------ | ------------------------------------- | :--------------: | :-----------: |
|
||||
| `EPOCHS_PER_HISTORICAL_VECTOR` | `uint64(2**16)` (= 65,536) | epochs | ~0.8 years |
|
||||
| `EPOCHS_PER_SLASHINGS_VECTOR` | `uint64(2**13)` (= 8,192) | epochs | ~36 days |
|
||||
| `HISTORICAL_ROOTS_LIMIT` | `uint64(2**24)` (= 16,777,216) | historical roots | ~52,262 years |
|
||||
| `VALIDATOR_REGISTRY_LIMIT` | `uint64(2**40)` (= 1,099,511,627,776) | validators | |
|
||||
|
||||
### Rewards and penalties
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `BASE_REWARD_FACTOR` | `uint64(2**6)` (= 64) |
|
||||
| `WHISTLEBLOWER_REWARD_QUOTIENT` | `uint64(2**9)` (= 512) |
|
||||
| `PROPOSER_REWARD_QUOTIENT` | `uint64(2**3)` (= 8) |
|
||||
| `INACTIVITY_PENALTY_QUOTIENT` | `uint64(2**26)` (= 67,108,864) |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT` | `uint64(2**7)` (= 128) |
|
||||
| `PROPORTIONAL_SLASHING_MULTIPLIER` | `uint64(1)` |
|
||||
| Name | Value |
|
||||
| ---------------------------------- | ------------------------------ |
|
||||
| `BASE_REWARD_FACTOR` | `uint64(2**6)` (= 64) |
|
||||
| `WHISTLEBLOWER_REWARD_QUOTIENT` | `uint64(2**9)` (= 512) |
|
||||
| `PROPOSER_REWARD_QUOTIENT` | `uint64(2**3)` (= 8) |
|
||||
| `INACTIVITY_PENALTY_QUOTIENT` | `uint64(2**26)` (= 67,108,864) |
|
||||
| `MIN_SLASHING_PENALTY_QUOTIENT` | `uint64(2**7)` (= 128) |
|
||||
| `PROPORTIONAL_SLASHING_MULTIPLIER` | `uint64(1)` |
|
||||
|
||||
- The `INACTIVITY_PENALTY_QUOTIENT` equals `INVERSE_SQRT_E_DROP_TIME**2` where `INVERSE_SQRT_E_DROP_TIME := 2**13` epochs (about 36 days) is the time it takes the inactivity penalty to reduce the balance of non-participating validators to about `1/sqrt(e) ~= 60.6%`. Indeed, the balance retained by offline validators after `n` epochs is about `(1 - 1/INACTIVITY_PENALTY_QUOTIENT)**(n**2/2)`; so after `INVERSE_SQRT_E_DROP_TIME` epochs, it is roughly `(1 - 1/INACTIVITY_PENALTY_QUOTIENT)**(INACTIVITY_PENALTY_QUOTIENT/2) ~= 1/sqrt(e)`. Note this value will be upgraded to `2**24` after Phase 0 mainnet stabilizes to provide a faster recovery in the event of an inactivity leak.
|
||||
|
||||
@@ -277,13 +272,13 @@ Additional preset configurations can be found in the [`configs`](../../configs)
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_PROPOSER_SLASHINGS` | `2**4` (= 16) |
|
||||
| `MAX_ATTESTER_SLASHINGS` | `2**1` (= 2) |
|
||||
| `MAX_ATTESTATIONS` | `2**7` (= 128) |
|
||||
| `MAX_DEPOSITS` | `2**4` (= 16) |
|
||||
| `MAX_VOLUNTARY_EXITS` | `2**4` (= 16) |
|
||||
| Name | Value |
|
||||
| ------------------------ | -------------- |
|
||||
| `MAX_PROPOSER_SLASHINGS` | `2**4` (= 16) |
|
||||
| `MAX_ATTESTER_SLASHINGS` | `2**1` (= 2) |
|
||||
| `MAX_ATTESTATIONS` | `2**7` (= 128) |
|
||||
| `MAX_DEPOSITS` | `2**4` (= 16) |
|
||||
| `MAX_VOLUNTARY_EXITS` | `2**4` (= 16) |
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -293,30 +288,30 @@ Testnets and other types of chain instances may use a different configuration.
|
||||
|
||||
### Genesis settings
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `uint64(2**14)` (= 16,384) |
|
||||
| `MIN_GENESIS_TIME` | `uint64(1606824000)` (Dec 1, 2020, 12pm UTC) |
|
||||
| `GENESIS_FORK_VERSION` | `Version('0x00000000')` |
|
||||
| `GENESIS_DELAY` | `uint64(604800)` (7 days) |
|
||||
| Name | Value |
|
||||
| ------------------------------------ | -------------------------------------------- |
|
||||
| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `uint64(2**14)` (= 16,384) |
|
||||
| `MIN_GENESIS_TIME` | `uint64(1606824000)` (Dec 1, 2020, 12pm UTC) |
|
||||
| `GENESIS_FORK_VERSION` | `Version('0x00000000')` |
|
||||
| `GENESIS_DELAY` | `uint64(604800)` (7 days) |
|
||||
|
||||
### Time parameters
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| `SECONDS_PER_SLOT` | `uint64(12)` | seconds | 12 seconds |
|
||||
| `SECONDS_PER_ETH1_BLOCK` | `uint64(14)` | seconds | 14 seconds |
|
||||
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `uint64(2**8)` (= 256) | epochs | ~27 hours |
|
||||
| `SHARD_COMMITTEE_PERIOD` | `uint64(2**8)` (= 256) | epochs | ~27 hours |
|
||||
| `ETH1_FOLLOW_DISTANCE` | `uint64(2**11)` (= 2,048) | Eth1 blocks | ~8 hours |
|
||||
| Name | Value | Unit | Duration |
|
||||
| ------------------------------------- | ------------------------- | :---------: | :--------: |
|
||||
| `SECONDS_PER_SLOT` | `uint64(12)` | seconds | 12 seconds |
|
||||
| `SECONDS_PER_ETH1_BLOCK` | `uint64(14)` | seconds | 14 seconds |
|
||||
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `uint64(2**8)` (= 256) | epochs | ~27 hours |
|
||||
| `SHARD_COMMITTEE_PERIOD` | `uint64(2**8)` (= 256) | epochs | ~27 hours |
|
||||
| `ETH1_FOLLOW_DISTANCE` | `uint64(2**11)` (= 2,048) | Eth1 blocks | ~8 hours |
|
||||
|
||||
### Validator cycle
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `EJECTION_BALANCE` | `Gwei(2**4 * 10**9)` (= 16,000,000,000) |
|
||||
| `MIN_PER_EPOCH_CHURN_LIMIT` | `uint64(2**2)` (= 4) |
|
||||
| `CHURN_LIMIT_QUOTIENT` | `uint64(2**16)` (= 65,536) |
|
||||
| Name | Value |
|
||||
| --------------------------- | --------------------------------------- |
|
||||
| `EJECTION_BALANCE` | `Gwei(2**4 * 10**9)` (= 16,000,000,000) |
|
||||
| `MIN_PER_EPOCH_CHURN_LIMIT` | `uint64(2**2)` (= 4) |
|
||||
| `CHURN_LIMIT_QUOTIENT` | `uint64(2**16)` (= 65,536) |
|
||||
|
||||
## Containers
|
||||
|
||||
@@ -624,7 +619,7 @@ def xor(bytes_1: Bytes32, bytes_2: Bytes32) -> Bytes32:
|
||||
|
||||
#### `uint_to_bytes`
|
||||
|
||||
`def uint_to_bytes(n: uint) -> bytes` is a function for serializing the `uint` type object to bytes in ``ENDIANNESS``-endian. The expected length of the output is the byte-length of the `uint` type.
|
||||
`def uint_to_bytes(n: uint) -> bytes` is a function for serializing the `uint` type object to bytes in `ENDIANNESS`-endian. The expected length of the output is the byte-length of the `uint` type.
|
||||
|
||||
#### `bytes_to_uint64`
|
||||
|
||||
@@ -1627,6 +1622,7 @@ def process_slashings(state: BeaconState) -> None:
|
||||
```
|
||||
|
||||
#### Eth1 data votes updates
|
||||
|
||||
```python
|
||||
def process_eth1_data_reset(state: BeaconState) -> None:
|
||||
next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||
@@ -1672,6 +1668,7 @@ def process_randao_mixes_reset(state: BeaconState) -> None:
|
||||
```
|
||||
|
||||
#### Historical roots updates
|
||||
|
||||
```python
|
||||
def process_historical_roots_update(state: BeaconState) -> None:
|
||||
# Set historical root accumulator
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Phase 0 -- Deposit Contract
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -16,8 +12,7 @@
|
||||
- [`DepositEvent` log](#depositevent-log)
|
||||
- [Solidity code](#solidity-code)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -27,8 +22,8 @@ This document represents the specification for the beacon chain deposit contract
|
||||
|
||||
The following values are (non-configurable) constants used throughout the specification.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ----------------------------- | ------------- |
|
||||
| `DEPOSIT_CONTRACT_TREE_DEPTH` | `2**5` (= 32) |
|
||||
|
||||
## Configuration
|
||||
@@ -37,10 +32,10 @@ The following values are (non-configurable) constants used throughout the specif
|
||||
The different configurations for mainnet, testnets, and YAML-based testing can be found in the [`configs/constant_presets`](../../configs) directory.
|
||||
These configurations are updated for releases and may be out of sync during `dev` changes.
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `DEPOSIT_CHAIN_ID` | `1` |
|
||||
| `DEPOSIT_NETWORK_ID` | `1` |
|
||||
| Name | Value |
|
||||
| -------------------------- | -------------------------------------------- |
|
||||
| `DEPOSIT_CHAIN_ID` | `1` |
|
||||
| `DEPOSIT_NETWORK_ID` | `1` |
|
||||
| `DEPOSIT_CONTRACT_ADDRESS` | `0x00000000219ab540356cBB839Cbe05303d7705Fa` |
|
||||
|
||||
## Staking deposit contract
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Phase 0 -- Beacon Chain Fork Choice
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Fork choice](#fork-choice)
|
||||
@@ -54,8 +50,7 @@
|
||||
- [`on_attestation`](#on_attestation)
|
||||
- [`on_attester_slashing`](#on_attester_slashing)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -74,11 +69,11 @@ Any of the above handlers that trigger an unhandled exception (e.g. a failed ass
|
||||
|
||||
*Notes*:
|
||||
|
||||
1) **Leap seconds**: Slots will last `SECONDS_PER_SLOT + 1` or `SECONDS_PER_SLOT - 1` seconds around leap seconds. This is automatically handled by [UNIX time](https://en.wikipedia.org/wiki/Unix_time).
|
||||
2) **Honest clocks**: Honest nodes are assumed to have clocks synchronized within `SECONDS_PER_SLOT` seconds of each other.
|
||||
3) **Eth1 data**: The large `ETH1_FOLLOW_DISTANCE` specified in the [honest validator document](./validator.md) should ensure that `state.latest_eth1_data` of the canonical beacon chain remains consistent with the canonical Ethereum proof-of-work chain. If not, emergency manual intervention will be required.
|
||||
4) **Manual forks**: Manual forks may arbitrarily change the fork choice rule but are expected to be enacted at epoch transitions, with the fork details reflected in `state.fork`.
|
||||
5) **Implementation**: The implementation found in this specification is constructed for ease of understanding rather than for optimization in computation, space, or any other resource. A number of optimized alternatives can be found [here](https://github.com/protolambda/lmd-ghost).
|
||||
1. **Leap seconds**: Slots will last `SECONDS_PER_SLOT + 1` or `SECONDS_PER_SLOT - 1` seconds around leap seconds. This is automatically handled by [UNIX time](https://en.wikipedia.org/wiki/Unix_time).
|
||||
2. **Honest clocks**: Honest nodes are assumed to have clocks synchronized within `SECONDS_PER_SLOT` seconds of each other.
|
||||
3. **Eth1 data**: The large `ETH1_FOLLOW_DISTANCE` specified in the [honest validator document](./validator.md) should ensure that `state.latest_eth1_data` of the canonical beacon chain remains consistent with the canonical Ethereum proof-of-work chain. If not, emergency manual intervention will be required.
|
||||
4. **Manual forks**: Manual forks may arbitrarily change the fork choice rule but are expected to be enacted at epoch transitions, with the fork details reflected in `state.fork`.
|
||||
5. **Implementation**: The implementation found in this specification is constructed for ease of understanding rather than for optimization in computation, space, or any other resource. A number of optimized alternatives can be found [here](https://github.com/protolambda/lmd-ghost).
|
||||
|
||||
### Constant
|
||||
|
||||
@@ -88,12 +83,12 @@ Any of the above handlers that trigger an unhandled exception (e.g. a failed ass
|
||||
|
||||
### Configuration
|
||||
|
||||
| Name | Value |
|
||||
| ------------------------------------- | ------------ |
|
||||
| `PROPOSER_SCORE_BOOST` | `uint64(40)` |
|
||||
| `REORG_HEAD_WEIGHT_THRESHOLD` | `uint64(20)` |
|
||||
| `REORG_PARENT_WEIGHT_THRESHOLD` | `uint64(160)`|
|
||||
| `REORG_MAX_EPOCHS_SINCE_FINALIZATION` | `Epoch(2)` |
|
||||
| Name | Value |
|
||||
| ------------------------------------- | ------------- |
|
||||
| `PROPOSER_SCORE_BOOST` | `uint64(40)` |
|
||||
| `REORG_HEAD_WEIGHT_THRESHOLD` | `uint64(20)` |
|
||||
| `REORG_PARENT_WEIGHT_THRESHOLD` | `uint64(160)` |
|
||||
| `REORG_MAX_EPOCHS_SINCE_FINALIZATION` | `Epoch(2)` |
|
||||
|
||||
- The proposer score boost and re-org weight threshold are percentage
|
||||
values that are measured with respect to the weight of a single committee. See
|
||||
@@ -407,17 +402,20 @@ def update_unrealized_checkpoints(store: Store, unrealized_justified_checkpoint:
|
||||
if unrealized_finalized_checkpoint.epoch > store.unrealized_finalized_checkpoint.epoch:
|
||||
store.unrealized_finalized_checkpoint = unrealized_finalized_checkpoint
|
||||
```
|
||||
|
||||
#### Proposer head and reorg helpers
|
||||
|
||||
_Implementing these helpers is optional_.
|
||||
|
||||
##### `is_head_late`
|
||||
|
||||
```python
|
||||
def is_head_late(store: Store, head_root: Root) -> bool:
|
||||
return not store.block_timeliness[head_root]
|
||||
```
|
||||
|
||||
##### `is_shuffling_stable`
|
||||
|
||||
```python
|
||||
def is_shuffling_stable(slot: Slot) -> bool:
|
||||
return slot % SLOTS_PER_EPOCH != 0
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Phase 0 -- Networking
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Network fundamentals](#network-fundamentals)
|
||||
@@ -83,7 +79,7 @@
|
||||
- [Why are attestations limited to be broadcast on gossip channels within `SLOTS_PER_EPOCH` slots?](#why-are-attestations-limited-to-be-broadcast-on-gossip-channels-within-slots_per_epoch-slots)
|
||||
- [Why are aggregate attestations broadcast to the global topic as `AggregateAndProof`s rather than just as `Attestation`s?](#why-are-aggregate-attestations-broadcast-to-the-global-topic-as-aggregateandproofs-rather-than-just-as-attestations)
|
||||
- [Why are we sending entire objects in the pubsub and not just hashes?](#why-are-we-sending-entire-objects-in-the-pubsub-and-not-just-hashes)
|
||||
- [Should clients gossip blocks if they *cannot* validate the proposer signature due to not yet being synced, not knowing the head block, etc?](#should-clients-gossip-blocks-if-they-cannot-validate-the-proposer-signature-due-to-not-yet-being-synced-not-knowing-the-head-block-etc)
|
||||
- [Should clients gossip blocks if they cannot validate the proposer signature due to not yet being synced, not knowing the head block, etc?](#should-clients-gossip-blocks-if-they-cannot-validate-the-proposer-signature-due-to-not-yet-being-synced-not-knowing-the-head-block-etc)
|
||||
- [How are we going to discover peers in a gossipsub topic?](#how-are-we-going-to-discover-peers-in-a-gossipsub-topic)
|
||||
- [How should fork version be used in practice?](#how-should-fork-version-be-used-in-practice)
|
||||
- [Req/Resp](#reqresp)
|
||||
@@ -111,8 +107,7 @@
|
||||
- [Why is there a limit on message sizes at all?](#why-is-there-a-limit-on-message-sizes-at-all)
|
||||
- [libp2p implementations matrix](#libp2p-implementations-matrix)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -183,36 +178,36 @@ See the [Rationale](#design-decision-rationale) section below for tradeoffs.
|
||||
|
||||
We define the following Python custom types for type hinting and readability:
|
||||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `NodeID` | `uint256` | node identifier |
|
||||
| `SubnetID` | `uint64` | subnet identifier |
|
||||
| Name | SSZ equivalent | Description |
|
||||
| ---------- | -------------- | ----------------- |
|
||||
| `NodeID` | `uint256` | node identifier |
|
||||
| `SubnetID` | `uint64` | subnet identifier |
|
||||
|
||||
### Constants
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit |
|
||||
| -------------- | ----- | :------------------------------: |
|
||||
| `NODE_ID_BITS` | `256` | The bit length of uint256 is 256 |
|
||||
|
||||
### Configuration
|
||||
|
||||
This section outlines configurations that are used in this spec.
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `MAX_PAYLOAD_SIZE` | `10 * 2**20` (= 10485760, 10 MiB) | The maximum allowed size of uncompressed payload in gossipsub messages and RPC chunks |
|
||||
| `MAX_REQUEST_BLOCKS` | `2**10` (= 1024) | Maximum number of blocks in a single request |
|
||||
| `EPOCHS_PER_SUBNET_SUBSCRIPTION` | `2**8` (= 256) | Number of epochs on a subnet subscription (~27 hours) |
|
||||
| `MIN_EPOCHS_FOR_BLOCK_REQUESTS` | `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months) | The minimum epoch range over which a node must serve blocks |
|
||||
| `ATTESTATION_PROPAGATION_SLOT_RANGE` | `32` | The maximum number of slots during which an attestation can be propagated |
|
||||
| `MAXIMUM_GOSSIP_CLOCK_DISPARITY` | `500` | The maximum **milliseconds** of clock disparity assumed between honest nodes |
|
||||
| `MESSAGE_DOMAIN_INVALID_SNAPPY` | `DomainType('0x00000000')` | 4-byte domain for gossip message-id isolation of *invalid* snappy messages |
|
||||
| `MESSAGE_DOMAIN_VALID_SNAPPY` | `DomainType('0x01000000')` | 4-byte domain for gossip message-id isolation of *valid* snappy messages |
|
||||
| `SUBNETS_PER_NODE` | `2` | The number of long-lived subnets a beacon node should be subscribed to |
|
||||
| `ATTESTATION_SUBNET_COUNT` | `2**6` (= 64) | The number of attestation subnets used in the gossipsub protocol. |
|
||||
| `ATTESTATION_SUBNET_EXTRA_BITS` | `0` | The number of extra bits of a NodeId to use when mapping to a subscribed subnet |
|
||||
| `ATTESTATION_SUBNET_PREFIX_BITS` | `int(ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS)` | |
|
||||
| `MAX_CONCURRENT_REQUESTS` | `2` | Maximum number of concurrent requests per protocol ID that a client may issue |
|
||||
| Name | Value | Description |
|
||||
| ------------------------------------ | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| `MAX_PAYLOAD_SIZE` | `10 * 2**20` (= 10485760, 10 MiB) | The maximum allowed size of uncompressed payload in gossipsub messages and RPC chunks |
|
||||
| `MAX_REQUEST_BLOCKS` | `2**10` (= 1024) | Maximum number of blocks in a single request |
|
||||
| `EPOCHS_PER_SUBNET_SUBSCRIPTION` | `2**8` (= 256) | Number of epochs on a subnet subscription (~27 hours) |
|
||||
| `MIN_EPOCHS_FOR_BLOCK_REQUESTS` | `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months) | The minimum epoch range over which a node must serve blocks |
|
||||
| `ATTESTATION_PROPAGATION_SLOT_RANGE` | `32` | The maximum number of slots during which an attestation can be propagated |
|
||||
| `MAXIMUM_GOSSIP_CLOCK_DISPARITY` | `500` | The maximum **milliseconds** of clock disparity assumed between honest nodes |
|
||||
| `MESSAGE_DOMAIN_INVALID_SNAPPY` | `DomainType('0x00000000')` | 4-byte domain for gossip message-id isolation of *invalid* snappy messages |
|
||||
| `MESSAGE_DOMAIN_VALID_SNAPPY` | `DomainType('0x01000000')` | 4-byte domain for gossip message-id isolation of *valid* snappy messages |
|
||||
| `SUBNETS_PER_NODE` | `2` | The number of long-lived subnets a beacon node should be subscribed to |
|
||||
| `ATTESTATION_SUBNET_COUNT` | `2**6` (= 64) | The number of attestation subnets used in the gossipsub protocol. |
|
||||
| `ATTESTATION_SUBNET_EXTRA_BITS` | `0` | The number of extra bits of a NodeId to use when mapping to a subscribed subnet |
|
||||
| `ATTESTATION_SUBNET_PREFIX_BITS` | `int(ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS)` | |
|
||||
| `MAX_CONCURRENT_REQUESTS` | `2` | Maximum number of concurrent requests per protocol ID that a client may issue |
|
||||
|
||||
### MetaData
|
||||
|
||||
@@ -289,8 +284,8 @@ Topic strings have form: `/eth2/ForkDigestValue/Name/Encoding`.
|
||||
This defines both the type of data being sent on the topic and how the data field of the message is encoded.
|
||||
|
||||
- `ForkDigestValue` - the lowercase hex-encoded (no "0x" prefix) bytes of `compute_fork_digest(current_fork_version, genesis_validators_root)` where
|
||||
- `current_fork_version` is the fork version of the epoch of the message to be sent on the topic
|
||||
- `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||
- `current_fork_version` is the fork version of the epoch of the message to be sent on the topic
|
||||
- `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||
- `Name` - see table below
|
||||
- `Encoding` - the encoding strategy describes a specific representation of bytes that will be transmitted over the wire.
|
||||
See the [Encodings](#Encodings) section for further details.
|
||||
@@ -307,10 +302,10 @@ Starting from Gossipsub v1.1, clients MUST enforce this by applying the `StrictN
|
||||
|
||||
The `message-id` of a gossipsub message MUST be the following 20 byte value computed from the message data:
|
||||
|
||||
* If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
- If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
the concatenation of `MESSAGE_DOMAIN_VALID_SNAPPY` with the snappy decompressed message data,
|
||||
i.e. `SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + snappy_decompress(message.data))[:20]`.
|
||||
* Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
- Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of
|
||||
the concatenation of `MESSAGE_DOMAIN_INVALID_SNAPPY` with the raw message data,
|
||||
i.e. `SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + message.data)[:20]`.
|
||||
|
||||
@@ -323,7 +318,7 @@ and (2) some message `data` can fail to snappy decompress altogether.
|
||||
The payload is carried in the `data` field of a gossipsub message, and varies depending on the topic:
|
||||
|
||||
| Name | Message Type |
|
||||
|----------------------------------|---------------------------|
|
||||
| -------------------------------- | ------------------------- |
|
||||
| `beacon_block` | `SignedBeaconBlock` |
|
||||
| `beacon_aggregate_and_proof` | `SignedAggregateAndProof` |
|
||||
| `beacon_attestation_{subnet_id}` | `Attestation` |
|
||||
@@ -372,8 +367,7 @@ The following validations MUST pass before forwarding the `signed_beacon_block`
|
||||
- _[REJECT]_ The block's parent (defined by `block.parent_root`) passes validation.
|
||||
- _[REJECT]_ The block is from a higher slot than its parent.
|
||||
- _[REJECT]_ The current `finalized_checkpoint` is an ancestor of `block` -- i.e.
|
||||
`get_checkpoint_block(store, block.parent_root, store.finalized_checkpoint.epoch)
|
||||
== store.finalized_checkpoint.root`
|
||||
`get_checkpoint_block(store, block.parent_root, store.finalized_checkpoint.epoch) == store.finalized_checkpoint.root`
|
||||
- _[REJECT]_ The block is proposed by the expected `proposer_index` for the block's slot
|
||||
in the context of the current shuffling (defined by `parent_root`/`slot`).
|
||||
If the `proposer_index` cannot immediately be verified against the expected shuffling,
|
||||
@@ -398,8 +392,7 @@ The following validations MUST pass before forwarding the `signed_aggregate_and_
|
||||
- _[IGNORE]_ `aggregate.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `aggregate.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= aggregate.data.slot`
|
||||
(a client MAY queue future aggregates for processing at the appropriate slot).
|
||||
- _[REJECT]_ The aggregate attestation's epoch matches its target -- i.e. `aggregate.data.target.epoch ==
|
||||
compute_epoch_at_slot(aggregate.data.slot)`
|
||||
- _[REJECT]_ The aggregate attestation's epoch matches its target -- i.e. `aggregate.data.target.epoch == compute_epoch_at_slot(aggregate.data.slot)`
|
||||
- _[REJECT]_ The number of aggregation bits matches the committee size -- i.e.
|
||||
`len(aggregation_bits) == len(get_beacon_committee(state, aggregate.data.slot, index))`.
|
||||
- _[REJECT]_ The aggregate attestation has participants --
|
||||
@@ -424,8 +417,7 @@ The following validations MUST pass before forwarding the `signed_aggregate_and_
|
||||
- _[REJECT]_ The aggregate attestation's target block is an ancestor of the block named in the LMD vote -- i.e.
|
||||
`get_checkpoint_block(store, aggregate.data.beacon_block_root, aggregate.data.target.epoch) == aggregate.data.target.root`
|
||||
- _[IGNORE]_ The current `finalized_checkpoint` is an ancestor of the `block` defined by `aggregate.data.beacon_block_root` -- i.e.
|
||||
`get_checkpoint_block(store, aggregate.data.beacon_block_root, finalized_checkpoint.epoch)
|
||||
== store.finalized_checkpoint.root`
|
||||
`get_checkpoint_block(store, aggregate.data.beacon_block_root, finalized_checkpoint.epoch) == store.finalized_checkpoint.root`
|
||||
|
||||
###### `voluntary_exit`
|
||||
|
||||
@@ -487,8 +479,7 @@ The following validations MUST pass before forwarding the `attestation` on the s
|
||||
(within a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
|
||||
i.e. `attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= attestation.data.slot`
|
||||
(a client MAY queue future attestations for processing at the appropriate slot).
|
||||
- _[REJECT]_ The attestation's epoch matches its target -- i.e. `attestation.data.target.epoch ==
|
||||
compute_epoch_at_slot(attestation.data.slot)`
|
||||
- _[REJECT]_ The attestation's epoch matches its target -- i.e. `attestation.data.target.epoch == compute_epoch_at_slot(attestation.data.slot)`
|
||||
- _[REJECT]_ The attestation is unaggregated --
|
||||
that is, it has exactly one participating validator (`len([bit for bit in aggregation_bits if bit]) == 1`, i.e. exactly 1 bit is set).
|
||||
- _[REJECT]_ The number of aggregation bits matches the committee size -- i.e.
|
||||
@@ -503,8 +494,7 @@ The following validations MUST pass before forwarding the `attestation` on the s
|
||||
- _[REJECT]_ The attestation's target block is an ancestor of the block named in the LMD vote -- i.e.
|
||||
`get_checkpoint_block(store, attestation.data.beacon_block_root, attestation.data.target.epoch) == attestation.data.target.root`
|
||||
- _[IGNORE]_ The current `finalized_checkpoint` is an ancestor of the `block` defined by `attestation.data.beacon_block_root` -- i.e.
|
||||
`get_checkpoint_block(store, attestation.data.beacon_block_root, store.finalized_checkpoint.epoch)
|
||||
== store.finalized_checkpoint.root`
|
||||
`get_checkpoint_block(store, attestation.data.beacon_block_root, store.finalized_checkpoint.epoch) == store.finalized_checkpoint.root`
|
||||
|
||||
##### Attestations and Aggregation
|
||||
|
||||
@@ -541,9 +531,9 @@ Size limits are placed both on the [`RPCMsg`](https://github.com/libp2p/specs/bl
|
||||
|
||||
Clients MUST reject and MUST NOT emit or propagate messages whose size exceed the following limits:
|
||||
|
||||
* The size of the encoded `RPCMsg` (including control messages, framing, topics, etc) must not exceed `max_message_size()`.
|
||||
* The size of the compressed payload in the `Message.data` field must not exceed `max_compressed_len(MAX_PAYLOAD_SIZE)`.
|
||||
* The size of the uncompressed payload must not exceed `MAX_PAYLOAD_SIZE` or the [type-specific SSZ bound](#what-are-ssz-type-size-bounds), whichever is lower.
|
||||
- The size of the encoded `RPCMsg` (including control messages, framing, topics, etc) must not exceed `max_message_size()`.
|
||||
- The size of the compressed payload in the `Message.data` field must not exceed `max_compressed_len(MAX_PAYLOAD_SIZE)`.
|
||||
- The size of the uncompressed payload must not exceed `MAX_PAYLOAD_SIZE` or the [type-specific SSZ bound](#what-are-ssz-type-size-bounds), whichever is lower.
|
||||
|
||||
### The Req/Resp domain
|
||||
|
||||
@@ -612,6 +602,7 @@ The requester MUST NOT make more than `MAX_CONCURRENT_REQUESTS` concurrent reque
|
||||
If a timeout occurs or the response is no longer relevant, the requester SHOULD reset the stream.
|
||||
|
||||
A requester SHOULD read from the stream until either:
|
||||
|
||||
1. An error result is received in one of the chunks (the error payload MAY be read before stopping).
|
||||
2. The responder closes the stream.
|
||||
3. Any part of the `response_chunk` fails validation.
|
||||
@@ -630,7 +621,7 @@ The responder MUST:
|
||||
|
||||
1. Use the encoding strategy to read the optional header.
|
||||
2. If there are any length assertions for length `N`, it should read exactly `N` bytes from the stream, at which point an EOF should arise (no more bytes).
|
||||
Should this not be the case, it should be treated as a failure.
|
||||
Should this not be the case, it should be treated as a failure.
|
||||
3. Deserialize the expected type, and process the request.
|
||||
4. Write the response which may consist of zero or more `response_chunk`s (result, optional header, payload).
|
||||
5. Close their write side of the stream. At this point, the stream will be fully closed.
|
||||
@@ -647,12 +638,12 @@ For multiple chunks, only the last chunk is allowed to have a non-zero error cod
|
||||
|
||||
The response code can have one of the following values, encoded as a single unsigned byte:
|
||||
|
||||
- 0: **Success** -- a normal response follows, with contents matching the expected message schema and encoding specified in the request.
|
||||
- 1: **InvalidRequest** -- the contents of the request are semantically invalid, or the payload is malformed, or could not be understood.
|
||||
- 0: **Success** -- a normal response follows, with contents matching the expected message schema and encoding specified in the request.
|
||||
- 1: **InvalidRequest** -- the contents of the request are semantically invalid, or the payload is malformed, or could not be understood.
|
||||
The response payload adheres to the `ErrorMessage` schema (described below).
|
||||
- 2: **ServerError** -- the responder encountered an error while processing the request.
|
||||
- 2: **ServerError** -- the responder encountered an error while processing the request.
|
||||
The response payload adheres to the `ErrorMessage` schema (described below).
|
||||
- 3: **ResourceUnavailable** -- the responder does not have requested resource.
|
||||
- 3: **ResourceUnavailable** -- the responder does not have requested resource.
|
||||
The response payload adheres to the `ErrorMessage` schema (described below).
|
||||
*Note*: This response code is only valid as a response where specified.
|
||||
|
||||
@@ -678,7 +669,7 @@ The responder MAY penalise peers that concurrently open more than `MAX_CONCURREN
|
||||
The token of the negotiated protocol ID specifies the type of encoding to be used for the req/resp interaction.
|
||||
Only one value is possible at this time:
|
||||
|
||||
- `ssz_snappy`: The contents are first [SSZ-encoded](../../ssz/simple-serialize.md)
|
||||
- `ssz_snappy`: The contents are first [SSZ-encoded](../../ssz/simple-serialize.md)
|
||||
and then compressed with [Snappy](https://github.com/google/snappy) frames compression.
|
||||
For objects containing a single field, only the field is SSZ-encoded not a container with a single field.
|
||||
For example, the `BeaconBlocksByRoot` request is an SSZ-encoded list of `Root`'s.
|
||||
@@ -707,6 +698,7 @@ When Snappy is applied, it can be passed through a buffered Snappy writer to com
|
||||
When snappy is applied, it can be passed through a buffered Snappy reader to decompress frame by frame.
|
||||
|
||||
Before reading the payload, the header MUST be validated:
|
||||
|
||||
- The length-prefix MUST be encoded as an unsigned protobuf varint. It SHOULD be minimally encoded (i.e., without any redundant bytes) and MUST not exceed 10 bytes in length, which is sufficient to represent any `uint64` value. The length-prefix MUST be decoded into a type which supports the full range of `uint64` values.
|
||||
- The length-prefix is within the expected [size bounds derived from the payload SSZ type](#what-are-ssz-type-size-bounds) or `MAX_PAYLOAD_SIZE`, whichever is smaller.
|
||||
|
||||
@@ -715,10 +707,12 @@ After reading a valid header, the payload MAY be read, while maintaining the siz
|
||||
A reader MUST NOT read more than `max_compressed_len(n)` bytes after reading the SSZ length-prefix `n` from the header.
|
||||
|
||||
A reader MUST consider the following cases as invalid input:
|
||||
|
||||
- Any remaining bytes, after having read the `n` SSZ bytes. An EOF is expected if more bytes are read than required.
|
||||
- An early EOF, before fully reading the declared length-prefix worth of SSZ bytes.
|
||||
|
||||
In case of an invalid input (header or payload), a reader MUST:
|
||||
|
||||
- From requests: send back an error message, response code `InvalidRequest`. The request itself is ignored.
|
||||
- From responses: ignore the response, the response MUST be considered bad server behavior.
|
||||
|
||||
@@ -733,7 +727,7 @@ Each _successful_ `response_chunk` contains a single `SignedBeaconBlock` payload
|
||||
|
||||
##### Status v1
|
||||
|
||||
**Protocol ID:** ``/eth2/beacon_chain/req/status/1/``
|
||||
**Protocol ID:** `/eth2/beacon_chain/req/status/1/`
|
||||
|
||||
Request, Response Content:
|
||||
|
||||
@@ -750,9 +744,9 @@ Request, Response Content:
|
||||
The fields are, as seen by the client at the time of sending the message:
|
||||
|
||||
- `fork_digest`: The node's `ForkDigest` (`compute_fork_digest(current_fork_version, genesis_validators_root)`) where
|
||||
- `current_fork_version` is the fork version at the node's current epoch defined by the wall-clock time
|
||||
(not necessarily the epoch to which the node is sync)
|
||||
- `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||
- `current_fork_version` is the fork version at the node's current epoch defined by the wall-clock time
|
||||
(not necessarily the epoch to which the node is sync)
|
||||
- `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||
- `finalized_root`: `store.finalized_checkpoint.root` according to [fork choice](./fork-choice.md).
|
||||
(Note this defaults to `Root(b'\x00' * 32)` for the genesis finalized checkpoint).
|
||||
- `finalized_epoch`: `store.finalized_checkpoint.epoch` according to [fork choice](./fork-choice.md).
|
||||
@@ -769,8 +763,8 @@ Clients SHOULD immediately disconnect from one another following the handshake a
|
||||
|
||||
1. If `fork_digest` does not match the node's local `fork_digest`, since the client’s chain is on another fork.
|
||||
2. If the (`finalized_root`, `finalized_epoch`) shared by the peer is not in the client's chain at the expected epoch.
|
||||
For example, if Peer 1 sends (root, epoch) of (A, 5) and Peer 2 sends (B, 3) but Peer 1 has root C at epoch 3,
|
||||
then Peer 1 would disconnect because it knows that their chains are irreparably disjoint.
|
||||
For example, if Peer 1 sends (root, epoch) of (A, 5) and Peer 2 sends (B, 3) but Peer 1 has root C at epoch 3,
|
||||
then Peer 1 would disconnect because it knows that their chains are irreparably disjoint.
|
||||
|
||||
Once the handshake completes, the client with the lower `finalized_epoch` or `head_slot` (if the clients have equal `finalized_epoch`s)
|
||||
SHOULD request beacon blocks from its counterparty via the `BeaconBlocksByRange` request.
|
||||
@@ -781,7 +775,7 @@ Implementers are free to implement such behavior in their own way.
|
||||
|
||||
##### Goodbye v1
|
||||
|
||||
**Protocol ID:** ``/eth2/beacon_chain/req/goodbye/1/``
|
||||
**Protocol ID:** `/eth2/beacon_chain/req/goodbye/1/`
|
||||
|
||||
Request, Response Content:
|
||||
|
||||
@@ -1005,14 +999,14 @@ This integration enables the libp2p stack to subsequently form connections and s
|
||||
The Ethereum Node Record (ENR) for an Ethereum consensus client MUST contain the following entries
|
||||
(exclusive of the sequence number and signature, which MUST be present in an ENR):
|
||||
|
||||
- The compressed secp256k1 publickey, 33 bytes (`secp256k1` field).
|
||||
- The compressed secp256k1 publickey, 33 bytes (`secp256k1` field).
|
||||
|
||||
The ENR MAY contain the following entries:
|
||||
|
||||
- An IPv4 address (`ip` field) and/or IPv6 address (`ip6` field).
|
||||
- An IPv4 TCP port (`tcp` field) representing the local libp2p TCP listening port and/or the corresponding IPv6 port (`tcp6` field).
|
||||
- An IPv4 QUIC port (`quic` field) representing the local libp2p QUIC (UDP) listening port and/or the corresponding IPv6 port (`quic6` field).
|
||||
- An IPv4 UDP port (`udp` field) representing the local discv5 listening port and/or the corresponding IPv6 port (`udp6` field).
|
||||
- An IPv4 address (`ip` field) and/or IPv6 address (`ip6` field).
|
||||
- An IPv4 TCP port (`tcp` field) representing the local libp2p TCP listening port and/or the corresponding IPv6 port (`tcp6` field).
|
||||
- An IPv4 QUIC port (`quic` field) representing the local libp2p QUIC (UDP) listening port and/or the corresponding IPv6 port (`quic6` field).
|
||||
- An IPv4 UDP port (`udp` field) representing the local discv5 listening port and/or the corresponding IPv6 port (`udp6` field).
|
||||
|
||||
Specifications of these parameters can be found in the [ENR Specification](http://eips.ethereum.org/EIPS/eip-778).
|
||||
|
||||
@@ -1022,7 +1016,7 @@ The ENR `attnets` entry signifies the attestation subnet bitfield with the follo
|
||||
to more easily discover peers participating in particular attestation gossip subnets.
|
||||
|
||||
| Key | Value |
|
||||
|:----------|:------------------------------------------|
|
||||
| :-------- | :---------------------------------------- |
|
||||
| `attnets` | SSZ `Bitvector[ATTESTATION_SUBNET_COUNT]` |
|
||||
|
||||
If a node's `MetaData.attnets` has any non-zero bit, the ENR MUST include the `attnets` entry with the same value as `MetaData.attnets`.
|
||||
@@ -1035,7 +1029,7 @@ ENRs MUST carry a generic `eth2` key with an 16-byte value of the node's current
|
||||
and next fork epoch to ensure connections are made with peers on the intended Ethereum network.
|
||||
|
||||
| Key | Value |
|
||||
|:-------|:----------------|
|
||||
| :----- | :-------------- |
|
||||
| `eth2` | SSZ `ENRForkID` |
|
||||
|
||||
Specifically, the value of the `eth2` key MUST be the following SSZ encoded object (`ENRForkID`)
|
||||
@@ -1050,13 +1044,13 @@ Specifically, the value of the `eth2` key MUST be the following SSZ encoded obje
|
||||
|
||||
where the fields of `ENRForkID` are defined as
|
||||
|
||||
* `fork_digest` is `compute_fork_digest(current_fork_version, genesis_validators_root)` where
|
||||
* `current_fork_version` is the fork version at the node's current epoch defined by the wall-clock time
|
||||
(not necessarily the epoch to which the node is sync)
|
||||
* `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||
* `next_fork_version` is the fork version corresponding to the next planned hard fork at a future epoch.
|
||||
- `fork_digest` is `compute_fork_digest(current_fork_version, genesis_validators_root)` where
|
||||
- `current_fork_version` is the fork version at the node's current epoch defined by the wall-clock time
|
||||
(not necessarily the epoch to which the node is sync)
|
||||
- `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||
- `next_fork_version` is the fork version corresponding to the next planned hard fork at a future epoch.
|
||||
If no future fork is planned, set `next_fork_version = current_fork_version` to signal this fact
|
||||
* `next_fork_epoch` is the epoch at which the next fork is planned and the `current_fork_version` will be updated.
|
||||
- `next_fork_epoch` is the epoch at which the next fork is planned and the `current_fork_version` will be updated.
|
||||
If no future fork is planned, set `next_fork_epoch = FAR_FUTURE_EPOCH` to signal this fact
|
||||
|
||||
*Note*: `fork_digest` is composed of values that are not known until the genesis block/state are available.
|
||||
@@ -1076,9 +1070,9 @@ these connecting clients will be unable to successfully interact starting at the
|
||||
|
||||
Because Phase 0 does not have shards and thus does not have Shard Committees, there is no stable backbone to the attestation subnets (`beacon_attestation_{subnet_id}`). To provide this stability, each beacon node should:
|
||||
|
||||
* Remain subscribed to `SUBNETS_PER_NODE` for `EPOCHS_PER_SUBNET_SUBSCRIPTION` epochs.
|
||||
* Maintain advertisement of the selected subnets in their node's ENR `attnets` entry by setting the selected `subnet_id` bits to `True` (e.g. `ENR["attnets"][subnet_id] = True`) for all persistent attestation subnets.
|
||||
* Select these subnets based on their node-id as specified by the following `compute_subscribed_subnets(node_id, epoch)` function.
|
||||
- Remain subscribed to `SUBNETS_PER_NODE` for `EPOCHS_PER_SUBNET_SUBSCRIPTION` epochs.
|
||||
- Maintain advertisement of the selected subnets in their node's ENR `attnets` entry by setting the selected `subnet_id` bits to `True` (e.g. `ENR["attnets"][subnet_id] = True`) for all persistent attestation subnets.
|
||||
- Select these subnets based on their node-id as specified by the following `compute_subscribed_subnets(node_id, epoch)` function.
|
||||
|
||||
```python
|
||||
def compute_subscribed_subnet(node_id: NodeID, epoch: Epoch, index: int) -> SubnetID:
|
||||
@@ -1118,8 +1112,8 @@ However, it is useful to define a minimum baseline for interoperability purposes
|
||||
Clients may support other transports such as libp2p QUIC, WebSockets, and WebRTC transports, if available in the language of choice.
|
||||
While interoperability shall not be harmed by lack of such support, the advantages are desirable:
|
||||
|
||||
- Better latency, performance, and other QoS characteristics (QUIC).
|
||||
- Paving the way for interfacing with future light clients (WebSockets, WebRTC).
|
||||
- Better latency, performance, and other QoS characteristics (QUIC).
|
||||
- Paving the way for interfacing with future light clients (WebSockets, WebRTC).
|
||||
|
||||
The libp2p QUIC transport inherently relies on TLS 1.3 per requirement in section 7
|
||||
of the [QUIC protocol specification](https://tools.ietf.org/html/draft-ietf-quic-transport-22#section-7)
|
||||
@@ -1240,7 +1234,7 @@ SecIO is not considered secure for the purposes of this spec.
|
||||
Copied from the Noise Protocol Framework [website](http://www.noiseprotocol.org):
|
||||
|
||||
> Noise is a framework for building crypto protocols.
|
||||
Noise protocols support mutual and optional authentication, identity hiding, forward secrecy, zero round-trip encryption, and other advanced features.
|
||||
> Noise protocols support mutual and optional authentication, identity hiding, forward secrecy, zero round-trip encryption, and other advanced features.
|
||||
|
||||
Noise in itself does not specify a single handshake procedure,
|
||||
but provides a framework to build secure handshakes based on Diffie-Hellman key agreement with a variety of tradeoffs and guarantees.
|
||||
@@ -1319,6 +1313,7 @@ so hashing topics would bloat messages unnecessarily.
|
||||
#### Why are we using the `StrictNoSign` signature policy?
|
||||
|
||||
The policy omits the `from` (1), `seqno` (3), `signature` (5) and `key` (6) fields. These fields would:
|
||||
|
||||
- Expose origin of sender (`from`), type of sender (based on `seqno`)
|
||||
- Add extra unused data to the gossip, since message IDs are based on `data`, not on the `from` and `seqno`.
|
||||
- Introduce more message validation than necessary, e.g. no `signature`.
|
||||
@@ -1330,10 +1325,10 @@ By overriding the default `message-id` to use content-addressing we can filter u
|
||||
|
||||
Some examples of where messages could be duplicated:
|
||||
|
||||
* A validator client connected to multiple beacon nodes publishing duplicate gossip messages
|
||||
* Attestation aggregation strategies where clients partially aggregate attestations and propagate them.
|
||||
- A validator client connected to multiple beacon nodes publishing duplicate gossip messages
|
||||
- Attestation aggregation strategies where clients partially aggregate attestations and propagate them.
|
||||
Partial aggregates could be duplicated
|
||||
* Clients re-publishing seen messages
|
||||
- Clients re-publishing seen messages
|
||||
|
||||
#### Why are these specific gossip parameters chosen?
|
||||
|
||||
@@ -1435,26 +1430,26 @@ This allows for handling sync and processing messages starting from past forks/e
|
||||
Requests are segregated by protocol ID to:
|
||||
|
||||
1. Leverage protocol routing in libp2p, such that the libp2p stack will route the incoming stream to the appropriate handler.
|
||||
This allows the handler function for each request type to be self-contained.
|
||||
For an analogy, think about how you attach HTTP handlers to a REST API server.
|
||||
This allows the handler function for each request type to be self-contained.
|
||||
For an analogy, think about how you attach HTTP handlers to a REST API server.
|
||||
2. Version requests independently.
|
||||
In a coarser-grained umbrella protocol, the entire protocol would have to be versioned even if just one field in a single message changed.
|
||||
In a coarser-grained umbrella protocol, the entire protocol would have to be versioned even if just one field in a single message changed.
|
||||
3. Enable clients to select the individual requests/versions they support.
|
||||
It would no longer be a strict requirement to support all requests,
|
||||
and clients, in principle, could support a subset of requests and variety of versions.
|
||||
It would no longer be a strict requirement to support all requests,
|
||||
and clients, in principle, could support a subset of requests and variety of versions.
|
||||
4. Enable flexibility and agility for clients adopting spec changes that impact the request, by signalling to peers exactly which subset of new/old requests they support.
|
||||
5. Enable clients to explicitly choose backwards compatibility at the request granularity.
|
||||
Without this, clients would be forced to support entire versions of the coarser request protocol.
|
||||
Without this, clients would be forced to support entire versions of the coarser request protocol.
|
||||
6. Parallelise RFCs (or EIPs).
|
||||
By decoupling requests from one another, each RFC that affects the request protocol can be deployed/tested/debated independently
|
||||
without relying on a synchronization point to version the general top-level protocol.
|
||||
By decoupling requests from one another, each RFC that affects the request protocol can be deployed/tested/debated independently
|
||||
without relying on a synchronization point to version the general top-level protocol.
|
||||
1. This has the benefit that clients can explicitly choose which RFCs to deploy
|
||||
without buying into all other RFCs that may be included in that top-level version.
|
||||
2. Affording this level of granularity with a top-level protocol would imply creating as many variants
|
||||
(e.g. /protocol/43-{a,b,c,d,...}) as the cartesian product of RFCs in-flight, O(n^2).
|
||||
7. Allow us to simplify the payload of requests.
|
||||
Request-id’s and method-ids no longer need to be sent.
|
||||
The encoding/request type and version can all be handled by the framework.
|
||||
Request-id’s and method-ids no longer need to be sent.
|
||||
The encoding/request type and version can all be handled by the framework.
|
||||
|
||||
**Caveat**: The protocol negotiation component in the current version of libp2p is called multistream-select 1.0.
|
||||
It is somewhat naïve and introduces overhead on every request when negotiating streams,
|
||||
@@ -1472,10 +1467,10 @@ We can therefore use stream closure to mark the end of the request and response
|
||||
|
||||
Nevertheless, in the case of `ssz_snappy`, messages are still length-prefixed with the length of the underlying data:
|
||||
|
||||
* A basic reader can prepare a correctly sized buffer before reading the message
|
||||
* A more advanced reader can stream-decode SSZ given the length of the SSZ data.
|
||||
* Alignment with protocols like gRPC over HTTP/2 that prefix with length
|
||||
* Sanity checking of message length, and enabling much stricter message length limiting based on SSZ type information,
|
||||
- A basic reader can prepare a correctly sized buffer before reading the message
|
||||
- A more advanced reader can stream-decode SSZ given the length of the SSZ data.
|
||||
- Alignment with protocols like gRPC over HTTP/2 that prefix with length
|
||||
- Sanity checking of message length, and enabling much stricter message length limiting based on SSZ type information,
|
||||
to provide even more DOS protection than the global message length already does.
|
||||
E.g. a small `Status` message does not nearly require `MAX_PAYLOAD_SIZE` bytes.
|
||||
|
||||
@@ -1527,9 +1522,9 @@ When requesting blocks by range or root, it may happen that there are no blocks
|
||||
|
||||
Thus, it may happen that we need to transmit an empty list - there are several ways to encode this:
|
||||
|
||||
0) Close the stream without sending any data
|
||||
1) Add a `null` option to the `success` response, for example by introducing an additional byte
|
||||
2) Respond with an error result, using a specific error code for "No data"
|
||||
0. Close the stream without sending any data
|
||||
1. Add a `null` option to the `success` response, for example by introducing an additional byte
|
||||
2. Respond with an error result, using a specific error code for "No data"
|
||||
|
||||
Semantically, it is not an error that a block is missing during a slot making option 2 unnatural.
|
||||
|
||||
@@ -1573,7 +1568,7 @@ the epoch range that a new node syncing from a checkpoint must backfill.
|
||||
[weak subjectivity guide](./weak-subjectivity.md). Specifically to find this max epoch range, we use the worst case event of a very large validator size
|
||||
(`>= MIN_PER_EPOCH_CHURN_LIMIT * CHURN_LIMIT_QUOTIENT`).
|
||||
|
||||
[0]: # (eth2spec: skip)
|
||||
<!-- eth2spec: skip -->
|
||||
|
||||
```python
|
||||
MIN_EPOCHS_FOR_BLOCK_REQUESTS = (
|
||||
@@ -1645,7 +1640,7 @@ discv5 uses ENRs and we will presumably need to:
|
||||
|
||||
1. Add `multiaddr` to the dictionary, so that nodes can advertise their multiaddr under a reserved namespace in ENRs. – and/or –
|
||||
2. Define a bi-directional conversion function between multiaddrs and the corresponding denormalized fields in an ENR
|
||||
(ip, ip6, tcp, tcp6, etc.), for compatibility with nodes that do not support multiaddr natively (e.g. Ethereum execution-layer nodes).
|
||||
(ip, ip6, tcp, tcp6, etc.), for compatibility with nodes that do not support multiaddr natively (e.g. Ethereum execution-layer nodes).
|
||||
|
||||
#### Why do we not form ENRs and find peers until genesis block/state is known?
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
This is an accompanying document to [Phase 0 -- The Beacon Chain](./beacon-chain.md), which describes the expected actions of a "validator" participating in the Ethereum proof-of-stake protocol.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -68,8 +64,7 @@ This is an accompanying document to [Phase 0 -- The Beacon Chain](./beacon-chain
|
||||
- [Attester slashing](#attester-slashing)
|
||||
- [Protection best practices](#protection-best-practices)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -85,8 +80,8 @@ All terminology, constants, functions, and protocol mechanics defined in the [Ph
|
||||
|
||||
### Misc
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| Name | Value | Unit |
|
||||
| ---------------------------------- | ------------- | :--------: |
|
||||
| `TARGET_AGGREGATORS_PER_COMMITTEE` | `2**4` (= 16) | validators |
|
||||
|
||||
## Containers
|
||||
@@ -141,8 +136,8 @@ Withdrawal credentials with the BLS withdrawal prefix allow a BLS key pair
|
||||
`(bls_withdrawal_privkey, bls_withdrawal_pubkey)` to trigger withdrawals.
|
||||
The `withdrawal_credentials` field must be such that:
|
||||
|
||||
* `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`
|
||||
* `withdrawal_credentials[1:] == hash(bls_withdrawal_pubkey)[1:]`
|
||||
- `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`
|
||||
- `withdrawal_credentials[1:] == hash(bls_withdrawal_pubkey)[1:]`
|
||||
|
||||
*Note*: The `bls_withdrawal_privkey` is not required for validating and can be kept in cold storage.
|
||||
|
||||
@@ -154,9 +149,9 @@ The `eth1_withdrawal_address` can be the address of either an externally owned a
|
||||
|
||||
The `withdrawal_credentials` field must be such that:
|
||||
|
||||
* `withdrawal_credentials[:1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX`
|
||||
* `withdrawal_credentials[1:12] == b'\x00' * 11`
|
||||
* `withdrawal_credentials[12:] == eth1_withdrawal_address`
|
||||
- `withdrawal_credentials[:1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX`
|
||||
- `withdrawal_credentials[1:12] == b'\x00' * 11`
|
||||
- `withdrawal_credentials[12:] == eth1_withdrawal_address`
|
||||
|
||||
After the merge of the current Ethereum execution layer into the Beacon Chain,
|
||||
withdrawals to `eth1_withdrawal_address` will simply be increases to the account's ETH balance that do **NOT** trigger any EVM execution.
|
||||
@@ -257,12 +252,12 @@ slot and joining the committee index attestation subnet related to their committ
|
||||
|
||||
Specifically a validator should:
|
||||
|
||||
* Call `_, committee_index, _ = get_committee_assignment(state, next_epoch, validator_index)` when checking for next epoch assignments.
|
||||
* Calculate the committees per slot for the next epoch: `committees_per_slot = get_committee_count_per_slot(state, next_epoch)`
|
||||
* Calculate the subnet index: `subnet_id = compute_subnet_for_attestation(committees_per_slot, slot, committee_index)`
|
||||
* Find peers of the pubsub topic `beacon_attestation_{subnet_id}`.
|
||||
* If an _insufficient_ number of current peers are subscribed to the topic, the validator must discover new peers on this topic. Via the discovery protocol, find peers with an ENR containing the `attnets` entry such that `ENR["attnets"][subnet_id] == True`. Then validate that the peers are still persisted on the desired topic by requesting `GetMetaData` and checking the resulting `attnets` field.
|
||||
* If the validator is assigned to be an aggregator for the slot (see `is_aggregator()`), then subscribe to the topic.
|
||||
- Call `_, committee_index, _ = get_committee_assignment(state, next_epoch, validator_index)` when checking for next epoch assignments.
|
||||
- Calculate the committees per slot for the next epoch: `committees_per_slot = get_committee_count_per_slot(state, next_epoch)`
|
||||
- Calculate the subnet index: `subnet_id = compute_subnet_for_attestation(committees_per_slot, slot, committee_index)`
|
||||
- Find peers of the pubsub topic `beacon_attestation_{subnet_id}`.
|
||||
- If an _insufficient_ number of current peers are subscribed to the topic, the validator must discover new peers on this topic. Via the discovery protocol, find peers with an ENR containing the `attnets` entry such that `ENR["attnets"][subnet_id] == True`. Then validate that the peers are still persisted on the desired topic by requesting `GetMetaData` and checking the resulting `attnets` field.
|
||||
- If the validator is assigned to be an aggregator for the slot (see `is_aggregator()`), then subscribe to the topic.
|
||||
|
||||
*Note*: If the validator is _not_ assigned to be an aggregator, the validator only needs sufficient number of peers on the topic to be able to publish messages. The validator does not need to _subscribe_ and listen to all messages on the topic.
|
||||
|
||||
@@ -408,7 +403,7 @@ Up to `MAX_ATTESTATIONS`, aggregate attestations can be included in the `block`.
|
||||
|
||||
##### Deposits
|
||||
|
||||
If there are any unprocessed deposits for the existing `state.eth1_data` (i.e. `state.eth1_data.deposit_count > state.eth1_deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, eth1_data.deposit_count - state.eth1_deposit_index)`. These [`deposits`](./beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [deposit contract](./deposit-contract.md) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](./beacon-chain.md#deposits).
|
||||
If there are any unprocessed deposits for the existing `state.eth1_data` (i.e. `state.eth1_data.deposit_count > state.eth1_deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, eth1_data.deposit_count - state.eth1_deposit_index)`. These [`deposits`](./beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [deposit contract](./deposit-contract.md) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](./beacon-chain.md#deposits).
|
||||
|
||||
The `proof` for each deposit must be constructed against the deposit root contained in `state.eth1_data` rather than the deposit root at the time the deposit was initially logged from the proof-of-work chain. This entails storing a full deposit merkle tree locally and computing updated proofs against the `eth1_data.deposit_root` as needed. See [`minimal_merkle.py`](https://github.com/ethereum/research/blob/master/spec_pythonizer/utils/merkle_minimal.py) for a sample implementation.
|
||||
|
||||
@@ -466,8 +461,8 @@ First, the validator should construct `attestation_data`, an [`AttestationData`]
|
||||
|
||||
##### General
|
||||
|
||||
* Set `attestation_data.slot = slot` where `slot` is the assigned slot.
|
||||
* Set `attestation_data.index = index` where `index` is the index associated with the validator's committee.
|
||||
- Set `attestation_data.slot = slot` where `slot` is the assigned slot.
|
||||
- Set `attestation_data.index = index` where `index` is the index associated with the validator's committee.
|
||||
|
||||
##### LMD GHOST vote
|
||||
|
||||
@@ -645,8 +640,8 @@ If the software crashes at some point within this routine, then when the validat
|
||||
|
||||
A validator client should be considered standalone and should consider the beacon node as untrusted. This means that the validator client should protect:
|
||||
|
||||
1) Private keys -- private keys should be protected from being exported accidentally or by an attacker.
|
||||
2) Slashing -- before a validator client signs a message it should validate the data, check it against a local slashing database (do not sign a slashable attestation or block) and update its internal slashing database with the newly signed object.
|
||||
3) Recovered validator -- Recovering a validator from a private key will result in an empty local slashing db. Best practice is to import (from a trusted source) that validator's attestation history. See [EIP 3076](https://github.com/ethereum/EIPs/pull/3076/files) for a standard slashing interchange format.
|
||||
4) Far future signing requests -- A validator client can be requested to sign a far into the future attestation, resulting in a valid non-slashable request. If the validator client signs this message, it will result in it blocking itself from attesting any other attestation until the beacon-chain reaches that far into the future epoch. This will result in an inactivity penalty and potential ejection due to low balance.
|
||||
A validator client should prevent itself from signing such requests by: a) keeping a local time clock if possible and following best practices to stop time server attacks and b) refusing to sign, by default, any message that has a large (>6h) gap from the current slashing protection database indicated a time "jump" or a long offline event. The administrator can manually override this protection to restart the validator after a genuine long offline event.
|
||||
1. Private keys -- private keys should be protected from being exported accidentally or by an attacker.
|
||||
2. Slashing -- before a validator client signs a message it should validate the data, check it against a local slashing database (do not sign a slashable attestation or block) and update its internal slashing database with the newly signed object.
|
||||
3. Recovered validator -- Recovering a validator from a private key will result in an empty local slashing db. Best practice is to import (from a trusted source) that validator's attestation history. See [EIP 3076](https://github.com/ethereum/EIPs/pull/3076/files) for a standard slashing interchange format.
|
||||
4. Far future signing requests -- A validator client can be requested to sign a far into the future attestation, resulting in a valid non-slashable request. If the validator client signs this message, it will result in it blocking itself from attesting any other attestation until the beacon-chain reaches that far into the future epoch. This will result in an inactivity penalty and potential ejection due to low balance.
|
||||
A validator client should prevent itself from signing such requests by: a) keeping a local time clock if possible and following best practices to stop time server attacks and b) refusing to sign, by default, any message that has a large (>6h) gap from the current slashing protection database indicated a time "jump" or a long offline event. The administrator can manually override this protection to restart the validator after a genuine long offline event.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Phase 0 -- Weak Subjectivity Guide
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Prerequisites](#prerequisites)
|
||||
@@ -21,8 +17,7 @@
|
||||
- [`is_within_weak_subjectivity_period`](#is_within_weak_subjectivity_period)
|
||||
- [Distributing Weak Subjectivity Checkpoints](#distributing-weak-subjectivity-checkpoints)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -40,20 +35,20 @@ This document uses data structures, constants, functions, and terminology from
|
||||
|
||||
## Custom Types
|
||||
|
||||
| Name | SSZ Equivalent | Description |
|
||||
| - | - | - |
|
||||
| `Ether` | `uint64` | an amount in Ether |
|
||||
| Name | SSZ Equivalent | Description |
|
||||
| ------- | -------------- | ------------------ |
|
||||
| `Ether` | `uint64` | an amount in Ether |
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| ------------- | --------------- |
|
||||
| `ETH_TO_GWEI` | `uint64(10**9)` |
|
||||
|
||||
## Configuration
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| Name | Value |
|
||||
| -------------- | ------------ |
|
||||
| `SAFETY_DECAY` | `uint64(10)` |
|
||||
|
||||
## Weak Subjectivity Checkpoint
|
||||
@@ -120,19 +115,19 @@ def compute_weak_subjectivity_period(state: BeaconState) -> uint64:
|
||||
A brief reference for what these values look like in practice ([reference script](https://gist.github.com/adiasg/3aceab409b36aa9a9d9156c1baa3c248)):
|
||||
|
||||
| Safety Decay | Avg. Val. Balance (ETH) | Val. Count | Weak Sub. Period (Epochs) |
|
||||
| ---- | ---- | ---- | ---- |
|
||||
| 10 | 28 | 32768 | 504 |
|
||||
| 10 | 28 | 65536 | 752 |
|
||||
| 10 | 28 | 131072 | 1248 |
|
||||
| 10 | 28 | 262144 | 2241 |
|
||||
| 10 | 28 | 524288 | 2241 |
|
||||
| 10 | 28 | 1048576 | 2241 |
|
||||
| 10 | 32 | 32768 | 665 |
|
||||
| 10 | 32 | 65536 | 1075 |
|
||||
| 10 | 32 | 131072 | 1894 |
|
||||
| 10 | 32 | 262144 | 3532 |
|
||||
| 10 | 32 | 524288 | 3532 |
|
||||
| 10 | 32 | 1048576 | 3532 |
|
||||
| ------------ | ----------------------- | ---------- | ------------------------- |
|
||||
| 10 | 28 | 32768 | 504 |
|
||||
| 10 | 28 | 65536 | 752 |
|
||||
| 10 | 28 | 131072 | 1248 |
|
||||
| 10 | 28 | 262144 | 2241 |
|
||||
| 10 | 28 | 524288 | 2241 |
|
||||
| 10 | 28 | 1048576 | 2241 |
|
||||
| 10 | 32 | 32768 | 665 |
|
||||
| 10 | 32 | 65536 | 1075 |
|
||||
| 10 | 32 | 131072 | 1894 |
|
||||
| 10 | 32 | 262144 | 3532 |
|
||||
| 10 | 32 | 524288 | 3532 |
|
||||
| 10 | 32 | 1048576 | 3532 |
|
||||
|
||||
## Weak Subjectivity Sync
|
||||
|
||||
@@ -151,12 +146,13 @@ If such a sync is not possible, the client should treat this as a critical and i
|
||||
```
|
||||
|
||||
2. Check the weak subjectivity requirements:
|
||||
- *IF* `epoch_number > store.finalized_checkpoint.epoch`,
|
||||
then *ASSERT* during block sync that block with root `block_root` is in the sync path at epoch `epoch_number`.
|
||||
Emit descriptive critical error if this assert fails, then exit client process.
|
||||
- *IF* `epoch_number <= store.finalized_checkpoint.epoch`,
|
||||
then *ASSERT* that the block in the canonical chain at epoch `epoch_number` has root `block_root`.
|
||||
Emit descriptive critical error if this assert fails, then exit client process.
|
||||
|
||||
- *IF* `epoch_number > store.finalized_checkpoint.epoch`,
|
||||
then *ASSERT* during block sync that block with root `block_root` is in the sync path at epoch `epoch_number`.
|
||||
Emit descriptive critical error if this assert fails, then exit client process.
|
||||
- *IF* `epoch_number <= store.finalized_checkpoint.epoch`,
|
||||
then *ASSERT* that the block in the canonical chain at epoch `epoch_number` has root `block_root`.
|
||||
Emit descriptive critical error if this assert fails, then exit client process.
|
||||
|
||||
### Checking for Stale Weak Subjectivity Checkpoint
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Merkle proof formats
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Generalized Merkle tree index](#generalized-merkle-tree-index)
|
||||
@@ -18,8 +14,7 @@
|
||||
- [`generalized_index_parent`](#generalized_index_parent)
|
||||
- [Merkle multiproofs](#merkle-multiproofs)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Helper functions
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# SimpleSerialize (SSZ)
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Constants](#constants)
|
||||
- [Typing](#typing)
|
||||
@@ -29,43 +25,43 @@
|
||||
- [Implementations](#implementations)
|
||||
- [JSON mapping](#json-mapping)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Constants
|
||||
|
||||
| Name | Value | Description |
|
||||
| - | - | - |
|
||||
| `BYTES_PER_CHUNK` | `32` | Number of bytes per chunk. |
|
||||
| `BYTES_PER_LENGTH_OFFSET` | `4` | Number of bytes per serialized length offset. |
|
||||
| `BITS_PER_BYTE` | `8` | Number of bits per byte. |
|
||||
| Name | Value | Description |
|
||||
| ------------------------- | ----- | --------------------------------------------- |
|
||||
| `BYTES_PER_CHUNK` | `32` | Number of bytes per chunk. |
|
||||
| `BYTES_PER_LENGTH_OFFSET` | `4` | Number of bytes per serialized length offset. |
|
||||
| `BITS_PER_BYTE` | `8` | Number of bits per byte. |
|
||||
|
||||
## Typing
|
||||
|
||||
### Basic types
|
||||
|
||||
* `uintN`: `N`-bit unsigned integer (where `N in [8, 16, 32, 64, 128, 256]`)
|
||||
* `byte`: 8-bit opaque data container, equivalent in serialization and hashing to `uint8`
|
||||
* `boolean`: `True` or `False`
|
||||
- `uintN`: `N`-bit unsigned integer (where `N in [8, 16, 32, 64, 128, 256]`)
|
||||
- `byte`: 8-bit opaque data container, equivalent in serialization and hashing to `uint8`
|
||||
- `boolean`: `True` or `False`
|
||||
|
||||
### Composite types
|
||||
|
||||
* **container**: ordered heterogeneous collection of values
|
||||
* python dataclass notation with key-type pairs, e.g.
|
||||
```python
|
||||
class ContainerExample(Container):
|
||||
foo: uint64
|
||||
bar: boolean
|
||||
```
|
||||
* **vector**: ordered fixed-length homogeneous collection, with `N` values
|
||||
* notation `Vector[type, N]`, e.g. `Vector[uint64, N]`
|
||||
* **list**: ordered variable-length homogeneous collection, limited to `N` values
|
||||
* notation `List[type, N]`, e.g. `List[uint64, N]`
|
||||
* **bitvector**: ordered fixed-length collection of `boolean` values, with `N` bits
|
||||
* notation `Bitvector[N]`
|
||||
* **bitlist**: ordered variable-length collection of `boolean` values, limited to `N` bits
|
||||
* notation `Bitlist[N]`
|
||||
* **union**: union type containing one of the given subtypes
|
||||
* notation `Union[type_0, type_1, ...]`, e.g. `union[None, uint64, uint32]`
|
||||
- **container**: ordered heterogeneous collection of values
|
||||
- python dataclass notation with key-type pairs, e.g.
|
||||
```python
|
||||
class ContainerExample(Container):
|
||||
foo: uint64
|
||||
bar: boolean
|
||||
```
|
||||
- **vector**: ordered fixed-length homogeneous collection, with `N` values
|
||||
- notation `Vector[type, N]`, e.g. `Vector[uint64, N]`
|
||||
- **list**: ordered variable-length homogeneous collection, limited to `N` values
|
||||
- notation `List[type, N]`, e.g. `List[uint64, N]`
|
||||
- **bitvector**: ordered fixed-length collection of `boolean` values, with `N` bits
|
||||
- notation `Bitvector[N]`
|
||||
- **bitlist**: ordered variable-length collection of `boolean` values, limited to `N` bits
|
||||
- notation `Bitlist[N]`
|
||||
- **union**: union type containing one of the given subtypes
|
||||
- notation `Union[type_0, type_1, ...]`, e.g. `union[None, uint64, uint32]`
|
||||
|
||||
*Note*: Both `Vector[boolean, N]` and `Bitvector[N]` are valid, yet distinct due to their different serialization requirements. Similarly, both `List[boolean, N]` and `Bitlist[N]` are valid, yet distinct. Generally `Bitvector[N]`/`Bitlist[N]` are preferred because of their serialization efficiencies.
|
||||
|
||||
@@ -81,25 +77,26 @@ Although the SSZ serialization of `byte` is equivalent to that of `uint8`, the f
|
||||
|
||||
For convenience we alias:
|
||||
|
||||
* `bit` to `boolean`
|
||||
* `BytesN` and `ByteVector[N]` to `Vector[byte, N]` (this is *not* a basic type)
|
||||
* `ByteList[N]` to `List[byte, N]`
|
||||
- `bit` to `boolean`
|
||||
- `BytesN` and `ByteVector[N]` to `Vector[byte, N]` (this is *not* a basic type)
|
||||
- `ByteList[N]` to `List[byte, N]`
|
||||
|
||||
Aliases are semantically equivalent to their underlying type and therefore share canonical representations both in SSZ and in related formats.
|
||||
|
||||
### Default values
|
||||
|
||||
Assuming a helper function `default(type)` which returns the default value for `type`, we can recursively define the default value for all types.
|
||||
|
||||
| Type | Default Value |
|
||||
| ---- | ------------- |
|
||||
| `uintN` | `0` |
|
||||
| `boolean` | `False` |
|
||||
| `Container` | `[default(type) for type in container]` |
|
||||
| `Vector[type, N]` | `[default(type)] * N` |
|
||||
| `Bitvector[N]` | `[False] * N` |
|
||||
| `List[type, N]` | `[]` |
|
||||
| `Bitlist[N]` | `[]` |
|
||||
| `Union[type_0, type_1, ...]` | `default(type_0)` |
|
||||
| Type | Default Value |
|
||||
| ---------------------------- | --------------------------------------- |
|
||||
| `uintN` | `0` |
|
||||
| `boolean` | `False` |
|
||||
| `Container` | `[default(type) for type in container]` |
|
||||
| `Vector[type, N]` | `[default(type)] * N` |
|
||||
| `Bitvector[N]` | `[False] * N` |
|
||||
| `List[type, N]` | `[]` |
|
||||
| `Bitlist[N]` | `[]` |
|
||||
| `Union[type_0, type_1, ...]` | `default(type_0)` |
|
||||
|
||||
#### `is_zero`
|
||||
|
||||
@@ -177,6 +174,7 @@ return b"".join(fixed_parts + variable_parts)
|
||||
A `value` as `Union[T...]` type has properties `value.value` with the contained value, and `value.selector` which indexes the selected `Union` type option `T`.
|
||||
|
||||
A `Union`:
|
||||
|
||||
- May have multiple selectors with the same type.
|
||||
- Should not use selectors above 127 (i.e. highest bit is set), these are reserved for backwards compatible extensions.
|
||||
- Must have at least 1 type option.
|
||||
@@ -200,12 +198,12 @@ Because serialization is an injective function (i.e. two distinct objects of the
|
||||
|
||||
Deserialization can be implemented using a recursive algorithm. The deserialization of basic objects is easy, and from there we can find a simple recursive algorithm for all fixed-size objects. For variable-size objects we have to do one of the following depending on what kind of object it is:
|
||||
|
||||
* Vector/list of a variable-size object: The serialized data will start with offsets of all the serialized objects (`BYTES_PER_LENGTH_OFFSET` bytes each).
|
||||
* Using the first offset, we can compute the length of the list (divide by `BYTES_PER_LENGTH_OFFSET`), as it gives us the total number of bytes in the offset data.
|
||||
* The size of each object in the vector/list can be inferred from the difference of two offsets. To get the size of the last object, the total number of bytes has to be known (it is not generally possible to deserialize an SSZ object of unknown length)
|
||||
* Containers follow the same principles as vectors, with the difference that there may be fixed-size objects in a container as well. This means the `fixed_parts` data will contain offsets as well as fixed-size objects.
|
||||
* In the case of bitlists, the length in bits cannot be uniquely inferred from the number of bytes in the object. Because of this, they have a bit at the end that is always set. This bit has to be used to infer the size of the bitlist in bits.
|
||||
* In the case of unions, the first byte of the deserialization scope is deserialized as type selector, the remainder of the scope is deserialized as the selected type.
|
||||
- Vector/list of a variable-size object: The serialized data will start with offsets of all the serialized objects (`BYTES_PER_LENGTH_OFFSET` bytes each).
|
||||
- Using the first offset, we can compute the length of the list (divide by `BYTES_PER_LENGTH_OFFSET`), as it gives us the total number of bytes in the offset data.
|
||||
- The size of each object in the vector/list can be inferred from the difference of two offsets. To get the size of the last object, the total number of bytes has to be known (it is not generally possible to deserialize an SSZ object of unknown length)
|
||||
- Containers follow the same principles as vectors, with the difference that there may be fixed-size objects in a container as well. This means the `fixed_parts` data will contain offsets as well as fixed-size objects.
|
||||
- In the case of bitlists, the length in bits cannot be uniquely inferred from the number of bytes in the object. Because of this, they have a bit at the end that is always set. This bit has to be used to infer the size of the bitlist in bits.
|
||||
- In the case of unions, the first byte of the deserialization scope is deserialized as type selector, the remainder of the scope is deserialized as the selected type.
|
||||
|
||||
Note that deserialization requires hardening against invalid inputs. A non-exhaustive list:
|
||||
|
||||
@@ -220,41 +218,41 @@ Efficient algorithms for computing this object can be found in [the implementati
|
||||
|
||||
We first define helper functions:
|
||||
|
||||
* `size_of(B)`, where `B` is a basic type: the length, in bytes, of the serialized form of the basic type.
|
||||
* `chunk_count(type)`: calculate the amount of leafs for merkleization of the type.
|
||||
* all basic types: `1`
|
||||
* `Bitlist[N]` and `Bitvector[N]`: `(N + 255) // 256` (dividing by chunk size, rounding up)
|
||||
* `List[B, N]` and `Vector[B, N]`, where `B` is a basic type: `(N * size_of(B) + 31) // 32` (dividing by chunk size, rounding up)
|
||||
* `List[C, N]` and `Vector[C, N]`, where `C` is a composite type: `N`
|
||||
* containers: `len(fields)`
|
||||
* `pack(values)`: Given ordered objects of the same basic type:
|
||||
1. Serialize `values` into bytes.
|
||||
2. If not aligned to a multiple of `BYTES_PER_CHUNK` bytes, right-pad with zeroes to the next multiple.
|
||||
3. Partition the bytes into `BYTES_PER_CHUNK`-byte chunks.
|
||||
4. Return the chunks.
|
||||
* `pack_bits(bits)`: Given the bits of bitlist or bitvector, get `bitfield_bytes` by packing them in bytes and aligning to the start. The length-delimiting bit for bitlists is excluded. Then return `pack(bitfield_bytes)`.
|
||||
* `next_pow_of_two(i)`: get the next power of 2 of `i`, if not already a power of 2, with 0 mapping to 1. Examples: `0->1, 1->1, 2->2, 3->4, 4->4, 6->8, 9->16`
|
||||
* `merkleize(chunks, limit=None)`: Given ordered `BYTES_PER_CHUNK`-byte chunks, merkleize the chunks, and return the root:
|
||||
* The merkleization depends on the effective input, which must be padded/limited:
|
||||
- if no limit: pad the `chunks` with zeroed chunks to `next_pow_of_two(len(chunks))` (virtually for memory efficiency).
|
||||
- if `limit >= len(chunks)`, pad the `chunks` with zeroed chunks to `next_pow_of_two(limit)` (virtually for memory efficiency).
|
||||
- if `limit < len(chunks)`: do not merkleize, input exceeds limit. Raise an error instead.
|
||||
* Then, merkleize the chunks (empty input is padded to 1 zero chunk):
|
||||
- If `1` chunk: the root is the chunk itself.
|
||||
- If `> 1` chunks: merkleize as binary tree.
|
||||
* `mix_in_length`: Given a Merkle root `root` and a length `length` (`"uint256"` little-endian serialization) return `hash(root + length)`.
|
||||
* `mix_in_selector`: Given a Merkle root `root` and a type selector `selector` (`"uint256"` little-endian serialization) return `hash(root + selector)`.
|
||||
- `size_of(B)`, where `B` is a basic type: the length, in bytes, of the serialized form of the basic type.
|
||||
- `chunk_count(type)`: calculate the amount of leafs for merkleization of the type.
|
||||
- all basic types: `1`
|
||||
- `Bitlist[N]` and `Bitvector[N]`: `(N + 255) // 256` (dividing by chunk size, rounding up)
|
||||
- `List[B, N]` and `Vector[B, N]`, where `B` is a basic type: `(N * size_of(B) + 31) // 32` (dividing by chunk size, rounding up)
|
||||
- `List[C, N]` and `Vector[C, N]`, where `C` is a composite type: `N`
|
||||
- containers: `len(fields)`
|
||||
- `pack(values)`: Given ordered objects of the same basic type:
|
||||
1. Serialize `values` into bytes.
|
||||
2. If not aligned to a multiple of `BYTES_PER_CHUNK` bytes, right-pad with zeroes to the next multiple.
|
||||
3. Partition the bytes into `BYTES_PER_CHUNK`-byte chunks.
|
||||
4. Return the chunks.
|
||||
- `pack_bits(bits)`: Given the bits of bitlist or bitvector, get `bitfield_bytes` by packing them in bytes and aligning to the start. The length-delimiting bit for bitlists is excluded. Then return `pack(bitfield_bytes)`.
|
||||
- `next_pow_of_two(i)`: get the next power of 2 of `i`, if not already a power of 2, with 0 mapping to 1. Examples: `0->1, 1->1, 2->2, 3->4, 4->4, 6->8, 9->16`
|
||||
- `merkleize(chunks, limit=None)`: Given ordered `BYTES_PER_CHUNK`-byte chunks, merkleize the chunks, and return the root:
|
||||
- The merkleization depends on the effective input, which must be padded/limited:
|
||||
- if no limit: pad the `chunks` with zeroed chunks to `next_pow_of_two(len(chunks))` (virtually for memory efficiency).
|
||||
- if `limit >= len(chunks)`, pad the `chunks` with zeroed chunks to `next_pow_of_two(limit)` (virtually for memory efficiency).
|
||||
- if `limit < len(chunks)`: do not merkleize, input exceeds limit. Raise an error instead.
|
||||
- Then, merkleize the chunks (empty input is padded to 1 zero chunk):
|
||||
- If `1` chunk: the root is the chunk itself.
|
||||
- If `> 1` chunks: merkleize as binary tree.
|
||||
- `mix_in_length`: Given a Merkle root `root` and a length `length` (`"uint256"` little-endian serialization) return `hash(root + length)`.
|
||||
- `mix_in_selector`: Given a Merkle root `root` and a type selector `selector` (`"uint256"` little-endian serialization) return `hash(root + selector)`.
|
||||
|
||||
We now define Merkleization `hash_tree_root(value)` of an object `value` recursively:
|
||||
|
||||
* `merkleize(pack(value))` if `value` is a basic object or a vector of basic objects.
|
||||
* `merkleize(pack_bits(value), limit=chunk_count(type))` if `value` is a bitvector.
|
||||
* `mix_in_length(merkleize(pack(value), limit=chunk_count(type)), len(value))` if `value` is a list of basic objects.
|
||||
* `mix_in_length(merkleize(pack_bits(value), limit=chunk_count(type)), len(value))` if `value` is a bitlist.
|
||||
* `merkleize([hash_tree_root(element) for element in value])` if `value` is a vector of composite objects or a container.
|
||||
* `mix_in_length(merkleize([hash_tree_root(element) for element in value], limit=chunk_count(type)), len(value))` if `value` is a list of composite objects.
|
||||
* `mix_in_selector(hash_tree_root(value.value), value.selector)` if `value` is of union type, and `value.value` is not `None`
|
||||
* `mix_in_selector(Bytes32(), 0)` if `value` is of union type, and `value.value` is `None`
|
||||
- `merkleize(pack(value))` if `value` is a basic object or a vector of basic objects.
|
||||
- `merkleize(pack_bits(value), limit=chunk_count(type))` if `value` is a bitvector.
|
||||
- `mix_in_length(merkleize(pack(value), limit=chunk_count(type)), len(value))` if `value` is a list of basic objects.
|
||||
- `mix_in_length(merkleize(pack_bits(value), limit=chunk_count(type)), len(value))` if `value` is a bitlist.
|
||||
- `merkleize([hash_tree_root(element) for element in value])` if `value` is a vector of composite objects or a container.
|
||||
- `mix_in_length(merkleize([hash_tree_root(element) for element in value], limit=chunk_count(type)), len(value))` if `value` is a list of composite objects.
|
||||
- `mix_in_selector(hash_tree_root(value.value), value.selector)` if `value` is of union type, and `value.value` is not `None`
|
||||
- `mix_in_selector(Bytes32(), 0)` if `value` is of union type, and `value.value` is `None`
|
||||
|
||||
## Summaries and expansions
|
||||
|
||||
@@ -272,19 +270,19 @@ The canonical JSON mapping assigns to each SSZ type a corresponding JSON encodin
|
||||
|
||||
When decoding JSON data, all fields in the SSZ schema must be present with a value. Parsers may ignore additional JSON fields.
|
||||
|
||||
| SSZ | JSON | Example |
|
||||
| --- | --- | --- |
|
||||
| `uintN` | string | `"0"` |
|
||||
| `byte` | hex-byte-string | `"0x00"` |
|
||||
| `boolean` | bool | `false` |
|
||||
| `Container` | object | `{ "field": ... }` |
|
||||
| `Vector[type, N]` | array | `[element, ...]` |
|
||||
| `Vector[byte, N]` | hex-byte-string | `"0x1122"` |
|
||||
| `Bitvector[N]` | hex-byte-string | `"0x1122"` |
|
||||
| `List[type, N]` | array | `[element, ...]` |
|
||||
| `List[byte, N]` | hex-byte-string | `"0x1122"` |
|
||||
| `Bitlist[N]` | hex-byte-string | `"0x1122"` |
|
||||
| `Union[type_0, type_1, ...]` | selector-object | `{ "selector": number, "data": type_N }` |
|
||||
| SSZ | JSON | Example |
|
||||
| ---------------------------- | --------------- | ---------------------------------------- |
|
||||
| `uintN` | string | `"0"` |
|
||||
| `byte` | hex-byte-string | `"0x00"` |
|
||||
| `boolean` | bool | `false` |
|
||||
| `Container` | object | `{ "field": ... }` |
|
||||
| `Vector[type, N]` | array | `[element, ...]` |
|
||||
| `Vector[byte, N]` | hex-byte-string | `"0x1122"` |
|
||||
| `Bitvector[N]` | hex-byte-string | `"0x1122"` |
|
||||
| `List[type, N]` | array | `[element, ...]` |
|
||||
| `List[byte, N]` | hex-byte-string | `"0x1122"` |
|
||||
| `Bitlist[N]` | hex-byte-string | `"0x1122"` |
|
||||
| `Union[type_0, type_1, ...]` | selector-object | `{ "selector": number, "data": type_N }` |
|
||||
|
||||
Integers are encoded as strings to avoid loss of precision in 64-bit values.
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# Optimistic Sync
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Constants](#constants)
|
||||
@@ -31,8 +27,7 @@
|
||||
- [What about Light Clients?](#what-about-light-clients)
|
||||
- [What if `TERMINAL_BLOCK_HASH` is used?](#what-if-terminal_block_hash-is-used)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
This document defines the YAML format and structure used for consensus spec testing.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
* [About](#about)
|
||||
+ [Test-case formats](#test-case-formats)
|
||||
@@ -26,7 +24,7 @@ This document defines the YAML format and structure used for consensus spec test
|
||||
* [Config sourcing](#config-sourcing)
|
||||
* [Note for implementers](#note-for-implementers)
|
||||
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## About
|
||||
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
The aim of the fork choice tests is to provide test coverage of the various components of the fork choice.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [Test case format](#test-case-format)
|
||||
- [`meta.yaml`](#metayaml)
|
||||
@@ -24,8 +20,7 @@ The aim of the fork choice tests is to provide test coverage of the various comp
|
||||
- [`block_<32-byte-root>.ssz_snappy`](#block_32-byte-rootssz_snappy)
|
||||
- [Condition](#condition)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- /TOC -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## Test case format
|
||||
|
||||
|
||||
@@ -9,10 +9,7 @@ On releases, test generators are run by the release manager. Test-generation of
|
||||
|
||||
An automated nightly tests release system, with a config filter applied, is being considered as implementation needs mature.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->
|
||||
|
||||
- [How to run generators](#how-to-run-generators)
|
||||
- [Cleaning](#cleaning)
|
||||
@@ -22,7 +19,7 @@ An automated nightly tests release system, with a config filter applied, is bein
|
||||
- [How to add a new test generator](#how-to-add-a-new-test-generator)
|
||||
- [How to remove a test generator](#how-to-remove-a-test-generator)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- mdformat-toc end -->
|
||||
|
||||
## How to run generators
|
||||
|
||||
|
||||
Reference in New Issue
Block a user