Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release v1.2.0 #2999

Merged
merged 33 commits into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
14d4f44
Extend fork_choice test format with on_payload_info
mkalinin Aug 3, 2022
109250b
Replace `hash_tree_root(x)` with `hash(ssz_serialize(x))`
hwwhww Aug 22, 2022
f8d92c3
Add basic test case
hwwhww Aug 15, 2022
b67fb5b
Update tests/formats/fork_choice/README.md
mkalinin Aug 24, 2022
d8e7409
Merge pull request #2981 from ethereum/hash_to_bls_field-with-serialize
asn-d6 Aug 25, 2022
ac717b1
Address PR feedback from @mkalinin
hwwhww Aug 31, 2022
0f8b5ae
Apply PR feedback from @michaelsproul
hwwhww Sep 2, 2022
2e73091
Add `get_valid_flag_value` helper to determine the `valid` flag value
hwwhww Sep 8, 2022
e639a3b
Merge branch 'dev' into pr2965
hwwhww Sep 8, 2022
97c61fe
Merge pull request #2965 from mkalinin/optimistic-sync-tests
hwwhww Sep 12, 2022
f2c2656
Merge pull request #2982 from ethereum/optimistic-sync-tests
hwwhww Sep 12, 2022
e4407c6
Add `test_process_deposit::test_key_validate_invalid`
hwwhww Sep 10, 2022
4d2cfff
Add `test_key_validate_invalid_decompression`
hwwhww Sep 12, 2022
770a603
Merge pull request #2989 from ethereum/deposit-zero-pk
djrtwo Sep 13, 2022
d70dcd9
Fix link to beacon-chain doc
barnjamin Sep 15, 2022
9a2fcc0
Merge pull request #2993 from barnjamin/patch-1
hwwhww Sep 16, 2022
63d284a
bump version to v1.2.0
djrtwo Sep 16, 2022
b63ed22
Fix signature of compute_aggregated_poly_and_commitment
dankrad Sep 19, 2022
b351550
Rename matrix_lincomb to vector_lincomb and lincomb to g1_lincomb
dankrad Sep 19, 2022
00a8a13
Merge pull request #2995 from ethereum/version-bump
djrtwo Sep 19, 2022
0f8e12e
Add a redirection README.md for the sync tests
hwwhww Sep 20, 2022
9ec97ba
Merge pull request #3000 from ethereum/sync-readme
djrtwo Sep 20, 2022
93b7ae2
Update BLS test format: output `null` for invalid case
hwwhww Sep 20, 2022
3bc7ff9
Fix a few things in Capella specs
jtraglia Sep 20, 2022
603e27f
Fix state list lengths table
jtraglia Sep 20, 2022
b72afff
Merge pull request #3002 from jtraglia/fix-a-few-things
ralexstokes Sep 21, 2022
7066307
Fix section name for withdraw_balance
jtraglia Sep 21, 2022
5517729
Fix TOC with check_toc
jtraglia Sep 21, 2022
1bb863b
eip4844: signed_blobs_header -> signed_blobs_sidecar
terencechain Sep 21, 2022
c0ef942
Merge pull request #3007 from jtraglia/rename-withdraw-section
hwwhww Sep 22, 2022
73c96b2
Merge pull request #3001 from ethereum/bls-output-null
hwwhww Sep 22, 2022
e4fdb8a
Merge pull request #3005 from ethereum/eip4844-patch-dr
asn-d6 Sep 22, 2022
189d61e
Merge pull request #3008 from terencechain/patch-137
ralexstokes Sep 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ def imports(cls, preset_name: str):
return super().imports(preset_name) + f'''
from eth2spec.utils import kzg
from eth2spec.bellatrix import {preset_name} as bellatrix
from eth2spec.utils.ssz.ssz_impl import serialize as ssz_serialize
'''

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion specs/altair/light-client/sync-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Such environments include resource-constrained devices (e.g. phones for trust-mi
and metered VMs (e.g. blockchain VMs for cross-chain bridges).

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).
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)
Expand Down
5 changes: 3 additions & 2 deletions specs/eip4844/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments:
```python
def hash_to_bls_field(x: Container) -> BLSFieldElement:
"""
This function is used to generate Fiat-Shamir challenges. The output is not uniform over the BLS field.
Compute 32-byte hash of serialized container and convert it to BLS field.
The output is not uniform over the BLS field.
"""
return int.from_bytes(hash_tree_root(x), "little") % BLS_MODULUS
return int.from_bytes(hash(ssz_serialize(x)), "little") % BLS_MODULUS
```

### `compute_powers`
Expand Down
4 changes: 2 additions & 2 deletions sync/optimistic.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ Let `current_slot: Slot` be `(time - genesis_time) // SECONDS_PER_SLOT` where
class OptimisticStore(object):
optimistic_roots: Set[Root]
head_block_root: Root
blocks: Dict[Root, BeaconBlock]
block_states: Dict[Root, BeaconState]
blocks: Dict[Root, BeaconBlock] = field(default_factory=dict)
block_states: Dict[Root, BeaconState] = field(default_factory=dict)
```

```python
Expand Down
2 changes: 1 addition & 1 deletion tests/core/pyspec/eth2spec/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.0-rc.3
1.2.0
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import json
from typing import Iterable, AnyStr, Any, Callable
import traceback

from ruamel.yaml import (
YAML,
)
Expand Down Expand Up @@ -98,6 +97,11 @@ def run_generator(generator_name, test_providers: Iterable[TestProvider]):
yaml = YAML(pure=True)
yaml.default_flow_style = None

def _represent_none(self, _):
return self.represent_scalar('tag:yaml.org,2002:null', 'null')

yaml.representer.add_representer(type(None), _represent_none)

# Spec config is using a YAML subset
cfg_yaml = YAML(pure=True)
cfg_yaml.default_flow_style = False # Emit separate line for each key
Expand Down
Empty file.
99 changes: 99 additions & 0 deletions tests/core/pyspec/eth2spec/test/bellatrix/sync/test_optimistic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from eth2spec.test.context import (
spec_state_test,
with_bellatrix_and_later,
)
from eth2spec.test.helpers.attestations import (
state_transition_with_full_block,
)
from eth2spec.test.helpers.block import (
build_empty_block_for_next_slot,
)
from eth2spec.test.helpers.fork_choice import (
get_genesis_forkchoice_store_and_block,
on_tick_and_append_step,
)
from eth2spec.test.helpers.optimistic_sync import (
PayloadStatusV1,
PayloadStatusV1Status,
MegaStore,
add_optimistic_block,
get_optimistic_store,
)
from eth2spec.test.helpers.state import (
next_epoch,
state_transition_and_sign_block,
)


@with_bellatrix_and_later
@spec_state_test
def test_from_syncing_to_invalid(spec, state):
test_steps = []
# Initialization
fc_store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
op_store = get_optimistic_store(spec, state, anchor_block)
mega_store = MegaStore(spec, fc_store, op_store)
yield 'anchor_state', state
yield 'anchor_block', anchor_block

next_epoch(spec, state)

current_time = (
(spec.SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY * 10 + state.slot) * spec.config.SECONDS_PER_SLOT
+ fc_store.genesis_time
)
on_tick_and_append_step(spec, fc_store, current_time, test_steps)

# Block 0
block_0 = build_empty_block_for_next_slot(spec, state)
block_0.body.execution_payload.block_hash = spec.hash(bytes(f'block_0', 'UTF-8'))
signed_block = state_transition_and_sign_block(spec, state, block_0)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root

state_0 = state.copy()

# Create VALID chain `a`
signed_blocks_a = []
for i in range(3):
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_a_{i}', 'UTF-8'))
block.body.execution_payload.parent_hash = (
spec.hash(bytes(f'chain_a_{i - 1}', 'UTF-8')) if i != 0 else block_0.body.execution_payload.block_hash
)

signed_block = state_transition_and_sign_block(spec, state, block)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root
signed_blocks_a.append(signed_block.copy())

# Create SYNCING chain `b`
signed_blocks_b = []
state = state_0.copy()
for i in range(3):
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_b_{i}', 'UTF-8'))
block.body.execution_payload.parent_hash = (
spec.hash(bytes(f'chain_b_{i - 1}', 'UTF-8')) if i != 0 else block_0.body.execution_payload.block_hash
)
signed_block = state_transition_with_full_block(spec, state, True, True, block=block)
signed_blocks_b.append(signed_block.copy())
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps,
status=PayloadStatusV1Status.SYNCING)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root

# Now add block 4 to chain `b` with INVALID
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_b_3', 'UTF-8'))
block.body.execution_payload.parent_hash = signed_blocks_b[-1].message.body.execution_payload.block_hash
signed_block = state_transition_and_sign_block(spec, state, block)
payload_status = PayloadStatusV1(
status=PayloadStatusV1Status.INVALID,
latest_valid_hash=block_0.body.execution_payload.block_hash,
validation_error="invalid",
)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps,
payload_status=payload_status)
assert mega_store.opt_store.head_block_root == signed_blocks_a[-1].message.hash_tree_root()

yield 'steps', test_steps
6 changes: 4 additions & 2 deletions tests/core/pyspec/eth2spec/test/helpers/attestations.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,13 @@ def state_transition_with_full_block(spec,
fill_cur_epoch,
fill_prev_epoch,
participation_fn=None,
sync_aggregate=None):
sync_aggregate=None,
block=None):
"""
Build and apply a block with attestions at the calculated `slot_to_attest` of current epoch and/or previous epoch.
"""
block = build_empty_block_for_next_slot(spec, state)
if block is None:
block = build_empty_block_for_next_slot(spec, state)
if fill_cur_epoch and state.slot >= spec.MIN_ATTESTATION_INCLUSION_DELAY:
slot_to_attest = state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1
if slot_to_attest >= spec.compute_start_slot_at_epoch(spec.get_current_epoch(state)):
Expand Down
15 changes: 11 additions & 4 deletions tests/core/pyspec/eth2spec/test/helpers/deposits.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,21 @@ def prepare_random_genesis_deposits(spec,
return deposits, root, deposit_data_list


def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False):
def prepare_state_and_deposit(spec, state, validator_index, amount,
pubkey=None,
privkey=None,
withdrawal_credentials=None,
signed=False):
"""
Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.
"""
deposit_data_list = []

pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
if pubkey is None:
pubkey = pubkeys[validator_index]

if privkey is None:
privkey = privkeys[validator_index]

# insecurely use pubkey as withdrawal key if no credentials provided
if withdrawal_credentials is None:
Expand Down Expand Up @@ -196,7 +203,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef

yield 'post', state

if not effective:
if not effective or not bls.KeyValidate(deposit.data.pubkey):
assert len(state.validators) == pre_validator_count
assert len(state.balances) == pre_validator_count
if validator_index < pre_validator_count:
Expand Down
80 changes: 40 additions & 40 deletions tests/core/pyspec/eth2spec/test/helpers/fork_choice.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,8 @@ def get_anchor_root(spec, state):
return spec.hash_tree_root(anchor_block_header)


def add_block_to_store(spec, store, signed_block):
pre_state = store.block_states[signed_block.message.parent_root]
block_time = pre_state.genesis_time + signed_block.message.slot * spec.config.SECONDS_PER_SLOT

if store.time < block_time:
spec.on_tick(store, block_time)

spec.on_block(store, signed_block)


def tick_and_add_block(spec, store, signed_block, test_steps, valid=True,
merge_block=False, block_not_found=False):
merge_block=False, block_not_found=False, is_optimistic=False):
pre_state = store.block_states[signed_block.message.parent_root]
block_time = pre_state.genesis_time + signed_block.message.slot * spec.config.SECONDS_PER_SLOT
if merge_block:
Expand All @@ -37,6 +27,7 @@ def tick_and_add_block(spec, store, signed_block, test_steps, valid=True,
spec, store, signed_block, test_steps,
valid=valid,
block_not_found=block_not_found,
is_optimistic=is_optimistic,
)

return post_state
Expand Down Expand Up @@ -119,28 +110,36 @@ def add_block(spec,
signed_block,
test_steps,
valid=True,
block_not_found=False):
block_not_found=False,
is_optimistic=False):
"""
Run on_block and on_attestation
"""
yield get_block_file_name(signed_block), signed_block

if not valid:
try:
if is_optimistic:
run_on_block(spec, store, signed_block, valid=True)
except (AssertionError, BlockNotFoundException) as e:
if isinstance(e, BlockNotFoundException) and not block_not_found:
assert False
test_steps.append({
'block': get_block_file_name(signed_block),
'valid': False,
})
return
else:
assert False

run_on_block(spec, store, signed_block, valid=True)
test_steps.append({'block': get_block_file_name(signed_block)})
try:
run_on_block(spec, store, signed_block, valid=True)
except (AssertionError, BlockNotFoundException) as e:
if isinstance(e, BlockNotFoundException) and not block_not_found:
assert False
test_steps.append({
'block': get_block_file_name(signed_block),
'valid': False,
})
return
else:
assert False
else:
run_on_block(spec, store, signed_block, valid=True)
test_steps.append({'block': get_block_file_name(signed_block)})

# An on_block step implies receiving block's attestations
for attestation in signed_block.message.body.attestations:
Expand All @@ -153,25 +152,26 @@ def add_block(spec,
block_root = signed_block.message.hash_tree_root()
assert store.blocks[block_root] == signed_block.message
assert store.block_states[block_root].hash_tree_root() == signed_block.message.state_root
test_steps.append({
'checks': {
'time': int(store.time),
'head': get_formatted_head_output(spec, store),
'justified_checkpoint': {
'epoch': int(store.justified_checkpoint.epoch),
'root': encode_hex(store.justified_checkpoint.root),
},
'finalized_checkpoint': {
'epoch': int(store.finalized_checkpoint.epoch),
'root': encode_hex(store.finalized_checkpoint.root),
},
'best_justified_checkpoint': {
'epoch': int(store.best_justified_checkpoint.epoch),
'root': encode_hex(store.best_justified_checkpoint.root),
},
'proposer_boost_root': encode_hex(store.proposer_boost_root),
}
})
if not is_optimistic:
test_steps.append({
'checks': {
'time': int(store.time),
'head': get_formatted_head_output(spec, store),
'justified_checkpoint': {
'epoch': int(store.justified_checkpoint.epoch),
'root': encode_hex(store.justified_checkpoint.root),
},
'finalized_checkpoint': {
'epoch': int(store.finalized_checkpoint.epoch),
'root': encode_hex(store.finalized_checkpoint.root),
},
'best_justified_checkpoint': {
'epoch': int(store.best_justified_checkpoint.epoch),
'root': encode_hex(store.best_justified_checkpoint.root),
},
'proposer_boost_root': encode_hex(store.proposer_boost_root),
}
})

return store.block_states[signed_block.message.hash_tree_root()]

Expand Down
Loading