Skip to content

Commit 0edd021

Browse files
authored
Merge pull request #3116 from ethereum/dev
Release v1.3.0-alpha.1 -- capella and 4844 prelease
2 parents 4c67744 + 208da34 commit 0edd021

File tree

103 files changed

+2812
-1132
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+2812
-1132
lines changed

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ CURRENT_DIR = ${CURDIR}
4141
LINTER_CONFIG_FILE = $(CURRENT_DIR)/linter.ini
4242
GENERATOR_ERROR_LOG_FILE = $(CURRENT_DIR)/$(TEST_VECTOR_DIR)/testgen_error_log.txt
4343

44+
SCRIPTS_DIR = ${CURRENT_DIR}/scripts
45+
4446
export DAPP_SKIP_BUILD:=1
4547
export DAPP_SRC:=$(SOLIDITY_DEPOSIT_CONTRACT_DIR)
4648
export DAPP_LIB:=$(SOLIDITY_DEPOSIT_CONTRACT_DIR)/lib
@@ -195,6 +197,14 @@ $(TEST_VECTOR_DIR):
195197
$(TEST_VECTOR_DIR)/:
196198
$(info ignoring duplicate tests dir)
197199

200+
gen_kzg_setups:
201+
cd $(SCRIPTS_DIR); \
202+
if ! test -d venv; then python3 -m venv venv; fi; \
203+
. venv/bin/activate; \
204+
pip3 install -r requirements.txt; \
205+
python3 ./gen_kzg_trusted_setups.py --secret=1337 --length=4 --output-dir ${CURRENT_DIR}/presets/minimal/trusted_setups; \
206+
python3 ./gen_kzg_trusted_setups.py --secret=1337 --length=4096 --output-dir ${CURRENT_DIR}/presets/mainnet/trusted_setups
207+
198208
# For any generator, build it using the run_generator function.
199209
# (creation of output dir is a dependency)
200210
gen_%: $(TEST_VECTOR_DIR)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Join the chat at https://discord.gg/qGpsxSA](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://discord.gg/qGpsxSA) [![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
44

5-
To learn more about proof-of-stake and sharding, see the [PoS FAQ](https://eth.wiki/en/concepts/proof-of-stake-faqs), [sharding FAQ](https://eth.wiki/sharding/Sharding-FAQs) and the [research compendium](https://notes.ethereum.org/s/H1PGqDhpm).
5+
To learn more about proof-of-stake and sharding, see the [PoS documentation](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/), [sharding documentation](https://ethereum.org/en/upgrades/sharding/) and the [research compendium](https://notes.ethereum.org/s/H1PGqDhpm).
66

77
This repository hosts the current Ethereum proof-of-stake specifications. Discussions about design rationale and proposed changes can be brought up and discussed as issues. Solidified, agreed-upon changes to the spec can be made through pull requests.
88

presets/mainnet/capella.yaml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,11 @@
11
# Mainnet preset - Capella
22

33
# Misc
4-
# ---------------------------------------------------------------
5-
# 2**8 (= 256) withdrawals
6-
MAX_PARTIAL_WITHDRAWALS_PER_EPOCH: 256
7-
8-
9-
# State list lengths
10-
# ---------------------------------------------------------------
11-
# 2**40 (= 1,099,511,627,776) withdrawals
12-
WITHDRAWAL_QUEUE_LIMIT: 1099511627776
13-
14-
154
# Max operations per block
165
# ---------------------------------------------------------------
176
# 2**4 (= 16)
187
MAX_BLS_TO_EXECUTION_CHANGES: 16
198

20-
219
# Execution
2210
# ---------------------------------------------------------------
2311
# 2**4 (= 16) withdrawals

presets/mainnet/trusted_setups/testing_trusted_setups.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

presets/minimal/capella.yaml

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
# Minimal preset - Capella
22

3-
# Misc
4-
# ---------------------------------------------------------------
5-
# [customized] 16 for more interesting tests at low validator count
6-
MAX_PARTIAL_WITHDRAWALS_PER_EPOCH: 16
7-
8-
9-
# State list lengths
10-
# ---------------------------------------------------------------
11-
# 2**40 (= 1,099,511,627,776) withdrawals
12-
WITHDRAWAL_QUEUE_LIMIT: 1099511627776
13-
14-
153
# Max operations per block
164
# ---------------------------------------------------------------
175
# 2**4 (= 16)
@@ -20,5 +8,5 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16
208

219
# Execution
2210
# ---------------------------------------------------------------
23-
# [customized] Lower than MAX_PARTIAL_WITHDRAWALS_PER_EPOCH so not all processed in one block
24-
MAX_WITHDRAWALS_PER_PAYLOAD: 8
11+
# [customized] 2**2 (= 4)
12+
MAX_WITHDRAWALS_PER_PAYLOAD: 4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"setup_G1": ["0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", "0x854262641262cb9e056a8512808ea6864d903dbcad713fd6da8dddfa5ce40d85612c912063ace060ed8c4bf005bab839", "0x86f708eee5ae0cf40be36993e760d9cb3b2371f22db3209947c5d21ea68e55186b30871c50bf11ef29e5248bf42d5678", "0x94f9c0bafb23cbbf34a93a64243e3e0f934b57593651f3464de7dc174468123d9698f1b9dfa22bb5b6eb96eae002f29f"], "setup_G2": ["0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", "0x99aca9fb2f7760cecb892bf7262c176b334824f5727f680bba701a33e322cb6667531410dfc7c8e4321a3f0ea8af48cb1436638a2093123f046f0f504cc2a864825542873edbbc5d7ed17af125a4f2cf6433c6f4f61b81173726981dd989761d", "0x88e2e982982bf8231e747e9dfcd14c05bd02623d1332734d2af26246c6869fb56ee6c994843f593178a040495ba61f4a083b0e18110b1d9f5224783d8f9a895e8ee744e87929430e9ba96bd29251cbf61240b256d1525600f3d562894d93d659", "0xa2d33775e3d9e6af0d1b27d389e6c021a578e617a3d6627686db6288d4b3dffd7a847a00f7ef01828b7f42885b660e4204923402aca18fbae74ccd4e9c50dd8c2281b38dc09c022342ed1ac695d53f7081cb21f05fdfc0a3508c04759196fcd3"], "setup_G1_lagrange": ["0x91131b2e3c1e5f0b51df8970e67080032f411571b66d301436c46f25bbfddf9ca16756430dc470bdb0d85b47fedcdbc1", "0x934d35b2a46e169915718b77127b0d4efbacdad7fdde4593af7d21d37ebcb77fe6c8dde6b8a9537854d70ef1f291a585", "0x9410ca1d0342fe7419f02194281df45e1c1ff42fd8b439de5644cc312815c21ddd2e3eeb63fb807cf837e68b76668bd5", "0xb163df7e9baeb60f69b6ee5faa538c3a564b62eb8cde6a3616083c8cb2171eedd583c9143e7e916df59bf27da5e024e8"], "roots_of_unity": [1, 3465144826073652318776269530687742778270252468765361963008, 52435875175126190479447740508185965837690552500527637822603658699938581184512, 52435875175126190475982595682112313518914282969839895044333406231173219221505]}

scripts/gen_kzg_trusted_setups.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import os
2+
from pathlib import Path
3+
4+
from eth2spec.utils.kzg import (
5+
dump_kzg_trusted_setup_files,
6+
)
7+
8+
9+
if __name__ == '__main__':
10+
import argparse
11+
12+
parser = argparse.ArgumentParser()
13+
parser.add_argument(
14+
"--secret",
15+
dest="secret",
16+
type=int,
17+
required=True,
18+
help='the secret of trusted setup',
19+
)
20+
parser.add_argument(
21+
"--length",
22+
dest="length",
23+
type=int,
24+
required=True,
25+
help='the length of trusted setup',
26+
)
27+
parser.add_argument(
28+
"-o",
29+
"--output-dir",
30+
dest="output_dir",
31+
required=True,
32+
help='the output directory',
33+
)
34+
args = parser.parse_args()
35+
36+
dump_kzg_trusted_setup_files(args.secret, args.length, args.output_dir)

scripts/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../[generator]

setup.py

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
import re
88
import string
99
import textwrap
10-
from typing import Dict, NamedTuple, List, Sequence, Optional, TypeVar
10+
from typing import Dict, NamedTuple, List, Sequence, Optional, TypeVar, Tuple
1111
from abc import ABC, abstractmethod
1212
import ast
1313
import subprocess
1414
import sys
1515
import copy
1616
from collections import OrderedDict
17+
import json
1718

1819

1920
# NOTE: have to programmatically include third-party dependencies in `setup.py`.
@@ -121,7 +122,7 @@ def _get_self_type_from_source(source: str) -> Optional[str]:
121122
return args[0].annotation.id
122123

123124

124-
def _get_class_info_from_source(source: str) -> (str, Optional[str]):
125+
def _get_class_info_from_source(source: str) -> Tuple[str, Optional[str]]:
125126
class_def = ast.parse(source).body[0]
126127
base = class_def.bases[0]
127128
if isinstance(base, ast.Name):
@@ -140,6 +141,28 @@ def _is_constant_id(name: str) -> bool:
140141
return all(map(lambda c: c in string.ascii_uppercase + '_' + string.digits, name[1:]))
141142

142143

144+
def _load_kzg_trusted_setups(preset_name):
145+
"""
146+
[TODO] it's not the final mainnet trusted setup.
147+
We will update it after the KZG ceremony.
148+
"""
149+
file_path = str(Path(__file__).parent) + '/presets/' + preset_name + '/trusted_setups/testing_trusted_setups.json'
150+
151+
with open(file_path, 'r') as f:
152+
json_data = json.load(f)
153+
154+
trusted_setup_G1 = json_data['setup_G1']
155+
trusted_setup_G2 = json_data['setup_G2']
156+
trusted_setup_G1_lagrange = json_data['setup_G1_lagrange']
157+
roots_of_unity = json_data['roots_of_unity']
158+
159+
return trusted_setup_G1, trusted_setup_G2, trusted_setup_G1_lagrange, roots_of_unity
160+
161+
ALL_KZG_SETUPS = {
162+
'minimal': _load_kzg_trusted_setups('minimal'),
163+
'mainnet': _load_kzg_trusted_setups('mainnet')
164+
}
165+
143166
ETH2_SPEC_COMMENT_PREFIX = "eth2spec:"
144167

145168

@@ -167,7 +190,16 @@ def _parse_value(name: str, typed_value: str, type_hint: Optional[str]=None) ->
167190
return VariableDefinition(type_name=type_name, value=typed_value[i+1:-1], comment=comment, type_hint=type_hint)
168191

169192

170-
def get_spec(file_name: Path, preset: Dict[str, str], config: Dict[str, str]) -> SpecObject:
193+
def _update_constant_vars_with_kzg_setups(constant_vars, preset_name):
194+
comment = "noqa: E501"
195+
kzg_setups = ALL_KZG_SETUPS[preset_name]
196+
constant_vars['KZG_SETUP_G1'] = VariableDefinition(constant_vars['KZG_SETUP_G1'].value, str(kzg_setups[0]), comment, None)
197+
constant_vars['KZG_SETUP_G2'] = VariableDefinition(constant_vars['KZG_SETUP_G2'].value, str(kzg_setups[1]), comment, None)
198+
constant_vars['KZG_SETUP_LAGRANGE'] = VariableDefinition(constant_vars['KZG_SETUP_LAGRANGE'].value, str(kzg_setups[2]), comment, None)
199+
constant_vars['ROOTS_OF_UNITY'] = VariableDefinition(constant_vars['ROOTS_OF_UNITY'].value, str(kzg_setups[3]), comment, None)
200+
201+
202+
def get_spec(file_name: Path, preset: Dict[str, str], config: Dict[str, str], preset_name=str) -> SpecObject:
171203
functions: Dict[str, str] = {}
172204
protocols: Dict[str, ProtocolDefinition] = {}
173205
constant_vars: Dict[str, VariableDefinition] = {}
@@ -232,7 +264,7 @@ def get_spec(file_name: Path, preset: Dict[str, str], config: Dict[str, str]) ->
232264

233265
if not _is_constant_id(name):
234266
# Check for short type declarations
235-
if value.startswith(("uint", "Bytes", "ByteList", "Union", "Vector", "List")):
267+
if value.startswith(("uint", "Bytes", "ByteList", "Union", "Vector", "List", "ByteVector")):
236268
custom_types[name] = value
237269
continue
238270

@@ -256,6 +288,10 @@ def get_spec(file_name: Path, preset: Dict[str, str], config: Dict[str, str]) ->
256288
if comment == "skip":
257289
should_skip = True
258290

291+
# Load KZG trusted setup from files
292+
if any('KZG_SETUP' in name for name in constant_vars):
293+
_update_constant_vars_with_kzg_setups(constant_vars, preset_name)
294+
259295
return SpecObject(
260296
functions=functions,
261297
protocols=protocols,
@@ -582,15 +618,13 @@ def imports(cls, preset_name: str):
582618
#
583619
# EIP4844SpecBuilder
584620
#
585-
class EIP4844SpecBuilder(BellatrixSpecBuilder):
621+
class EIP4844SpecBuilder(CapellaSpecBuilder):
586622
fork: str = EIP4844
587623

588624
@classmethod
589625
def imports(cls, preset_name: str):
590626
return super().imports(preset_name) + f'''
591-
from eth2spec.utils import kzg
592-
from eth2spec.bellatrix import {preset_name} as bellatrix
593-
from eth2spec.utils.ssz.ssz_impl import serialize as ssz_serialize
627+
from eth2spec.capella import {preset_name} as capella
594628
'''
595629

596630

@@ -603,33 +637,45 @@ def preparations(cls):
603637
@classmethod
604638
def sundry_functions(cls) -> str:
605639
return super().sundry_functions() + '\n\n' + '''
606-
# TODO: for mainnet, load pre-generated trusted setup file to reduce building time.
607-
# TESTING_FIELD_ELEMENTS_PER_BLOB is hardcoded copy from minimal presets
608-
TESTING_FIELD_ELEMENTS_PER_BLOB = 4
609-
TESTING_SECRET = 1337
610-
TESTING_KZG_SETUP_G1 = kzg.generate_setup(bls.G1, TESTING_SECRET, TESTING_FIELD_ELEMENTS_PER_BLOB)
611-
TESTING_KZG_SETUP_G2 = kzg.generate_setup(bls.G2, TESTING_SECRET, TESTING_FIELD_ELEMENTS_PER_BLOB)
612-
TESTING_KZG_SETUP_LAGRANGE = kzg.get_lagrange(TESTING_KZG_SETUP_G1)
640+
#
641+
# Temporarily disable Withdrawals functions for EIP4844 testnets
642+
#
613643
614-
KZG_SETUP_G1 = [bls.G1_to_bytes48(p) for p in TESTING_KZG_SETUP_G1]
615-
KZG_SETUP_G2 = [bls.G2_to_bytes96(p) for p in TESTING_KZG_SETUP_G2]
616-
KZG_SETUP_LAGRANGE = TESTING_KZG_SETUP_LAGRANGE
617-
ROOTS_OF_UNITY = kzg.compute_roots_of_unity(TESTING_FIELD_ELEMENTS_PER_BLOB)
618644
645+
def no_op(fn): # type: ignore
646+
def wrapper(*args, **kw): # type: ignore
647+
return None
648+
return wrapper
649+
650+
651+
def get_empty_list_result(fn): # type: ignore
652+
def wrapper(*args, **kw): # type: ignore
653+
return []
654+
return wrapper
619655
620-
def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> BlobsSidecar:
621-
pass'''
656+
657+
process_withdrawals = no_op(process_withdrawals)
658+
process_bls_to_execution_change = no_op(process_bls_to_execution_change)
659+
get_expected_withdrawals = get_empty_list_result(get_expected_withdrawals)
660+
661+
662+
#
663+
# End
664+
#
665+
666+
def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> Optional[BlobsSidecar]:
667+
return "TEST"'''
622668

623669
@classmethod
624670
def hardcoded_custom_type_dep_constants(cls, spec_object) -> str:
625671
constants = {
672+
'BYTES_PER_FIELD_ELEMENT': spec_object.constant_vars['BYTES_PER_FIELD_ELEMENT'].value,
626673
'FIELD_ELEMENTS_PER_BLOB': spec_object.preset_vars['FIELD_ELEMENTS_PER_BLOB'].value,
627674
'MAX_BLOBS_PER_BLOCK': spec_object.preset_vars['MAX_BLOBS_PER_BLOCK'].value,
628675
}
629676
return {**super().hardcoded_custom_type_dep_constants(spec_object), **constants}
630677

631678

632-
633679
spec_builders = {
634680
builder.fork: builder
635681
for builder in (Phase0SpecBuilder, AltairSpecBuilder, BellatrixSpecBuilder, CapellaSpecBuilder, EIP4844SpecBuilder)
@@ -880,7 +926,7 @@ def _build_spec(preset_name: str, fork: str,
880926
source_files: Sequence[Path], preset_files: Sequence[Path], config_file: Path) -> str:
881927
preset = load_preset(preset_files)
882928
config = load_config(config_file)
883-
all_specs = [get_spec(spec, preset, config) for spec in source_files]
929+
all_specs = [get_spec(spec, preset, config, preset_name) for spec in source_files]
884930

885931
spec_object = all_specs[0]
886932
for value in all_specs[1:]:
@@ -967,7 +1013,7 @@ def finalize_options(self):
9671013
specs/bellatrix/p2p-interface.md
9681014
sync/optimistic.md
9691015
"""
970-
if self.spec_fork == CAPELLA:
1016+
if self.spec_fork in (CAPELLA, EIP4844):
9711017
self.md_doc_paths += """
9721018
specs/capella/beacon-chain.md
9731019
specs/capella/fork.md
@@ -1131,7 +1177,7 @@ def run(self):
11311177
"pycryptodome==3.15.0",
11321178
"py_ecc==6.0.0",
11331179
"milagro_bls_binding==1.9.0",
1134-
"remerkleable==0.1.24",
1180+
"remerkleable==0.1.25",
11351181
RUAMEL_YAML_VERSION,
11361182
"lru-dict==1.1.8",
11371183
MARKO_VERSION,

specs/altair/light-client/full-node.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ def create_light_client_update(state: BeaconState,
8484
header = state.latest_block_header.copy()
8585
header.state_root = hash_tree_root(state)
8686
assert hash_tree_root(header) == hash_tree_root(block.message)
87-
update_signature_period = compute_sync_committee_period(compute_epoch_at_slot(block.message.slot))
87+
update_signature_period = compute_sync_committee_period_at_slot(block.message.slot)
8888

8989
assert attested_state.slot == attested_state.latest_block_header.slot
9090
attested_header = attested_state.latest_block_header.copy()
9191
attested_header.state_root = hash_tree_root(attested_state)
9292
assert hash_tree_root(attested_header) == block.message.parent_root
93-
update_attested_period = compute_sync_committee_period(compute_epoch_at_slot(attested_header.slot))
93+
update_attested_period = compute_sync_committee_period_at_slot(attested_header.slot)
9494

9595
# `next_sync_committee` is only useful if the message is signed by the current sync committee
9696
if update_attested_period == update_signature_period:
@@ -133,7 +133,7 @@ def create_light_client_update(state: BeaconState,
133133
Full nodes SHOULD provide the best derivable `LightClientUpdate` (according to `is_better_update`) for each sync committee period covering any epochs in range `[max(ALTAIR_FORK_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch]` where `current_epoch` is defined by the current wall-clock time. Full nodes MAY also provide `LightClientUpdate` for other sync committee periods.
134134

135135
- `LightClientUpdate` are assigned to sync committee periods based on their `attested_header.slot`
136-
- `LightClientUpdate` are only considered if `compute_sync_committee_period(compute_epoch_at_slot(update.attested_header.slot)) == compute_sync_committee_period(compute_epoch_at_slot(update.signature_slot))`
136+
- `LightClientUpdate` are only considered if `compute_sync_committee_period_at_slot(update.attested_header.slot) == compute_sync_committee_period_at_slot(update.signature_slot)`
137137
- Only `LightClientUpdate` with `next_sync_committee` as selected by fork choice are provided, regardless of ranking by `is_better_update`. To uniquely identify a non-finalized sync committee fork, all of `period`, `current_sync_committee` and `next_sync_committee` need to be incorporated, as sync committees may reappear over time.
138138

139139
### `create_light_client_finality_update`

0 commit comments

Comments
 (0)