Skip to content

Commit

Permalink
Merge branch 'dev' into peer-das
Browse files Browse the repository at this point in the history
  • Loading branch information
hwwhww committed Jan 19, 2024
2 parents 504b4f9 + 3727a75 commit 696d443
Show file tree
Hide file tree
Showing 29 changed files with 16,833 additions and 16,653 deletions.
16,510 changes: 8,255 additions & 8,255 deletions presets/mainnet/trusted_setups/trusted_setup_4096.json

Large diffs are not rendered by default.

16,510 changes: 8,255 additions & 8,255 deletions presets/minimal/trusted_setups/trusted_setup_4096.json

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions pysetup/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ def collect_prev_forks(fork: str) -> list[str]:
forks.append(fork)


def is_byte_vector(value: str) -> bool:
return value.startswith(('ByteVector'))
def requires_mypy_type_ignore(value: str) -> bool:
return (
value.startswith(('ByteVector'))
or (value.startswith(('Vector')) and 'floorlog2' in value)
)


def make_function_abstract(protocol_def: ProtocolDefinition, key: str):
Expand All @@ -41,7 +44,8 @@ def objects_to_spec(preset_name: str,
new_type_definitions = (
'\n\n'.join(
[
f"class {key}({value}):\n pass\n" if not is_byte_vector(value) else f"class {key}({value}): # type: ignore\n pass\n"
f"class {key}({value}):\n pass\n" if not requires_mypy_type_ignore(value)
else f"class {key}({value}): # type: ignore\n pass\n"
for key, value in spec_object.custom_types.items()
]
)
Expand Down Expand Up @@ -108,7 +112,7 @@ def format_constant(name: str, vardef: VariableDefinition) -> str:
if vardef.comment is not None:
out += f' # {vardef.comment}'
return out

# Merge all constant objects
hardcoded_ssz_dep_constants = reduce(lambda obj, builder: {**obj, **builder.hardcoded_ssz_dep_constants()}, builders, {})
hardcoded_custom_type_dep_constants = reduce(lambda obj, builder: {**obj, **builder.hardcoded_custom_type_dep_constants(spec_object)}, builders, {})
Expand All @@ -131,12 +135,13 @@ def format_constant(name: str, vardef: VariableDefinition) -> str:
imports,
preparations,
f"fork = \'{fork}\'\n",
# The helper functions that some SSZ containers require. Need to be defined before `custom_type_dep_constants`
CONSTANT_DEP_SUNDRY_CONSTANTS_FUNCTIONS,
# The constants that some SSZ containers require. Need to be defined before `new_type_definitions`
custom_type_dep_constants,
new_type_definitions,
CONSTANT_DEP_SUNDRY_CONSTANTS_FUNCTIONS,
# The constants that some SSZ containers require. Need to be defined before `constants_spec`
ssz_dep_constants,
new_type_definitions,
constant_vars_spec,
preset_vars_spec,
config_spec,
Expand Down
6 changes: 3 additions & 3 deletions pysetup/spec_builders/altair.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ def compute_merkle_proof(object: SSZObject,
@classmethod
def hardcoded_ssz_dep_constants(cls) -> Dict[str, str]:
return {
'FINALIZED_ROOT_INDEX': 'GeneralizedIndex(105)',
'CURRENT_SYNC_COMMITTEE_INDEX': 'GeneralizedIndex(54)',
'NEXT_SYNC_COMMITTEE_INDEX': 'GeneralizedIndex(55)',
'FINALIZED_ROOT_GINDEX': 'GeneralizedIndex(105)',
'CURRENT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(54)',
'NEXT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(55)',
}

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion pysetup/spec_builders/capella.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ def imports(cls, preset_name: str):
@classmethod
def hardcoded_ssz_dep_constants(cls) -> Dict[str, str]:
return {
'EXECUTION_PAYLOAD_INDEX': 'GeneralizedIndex(25)',
'EXECUTION_PAYLOAD_GINDEX': 'GeneralizedIndex(25)',
}
2 changes: 1 addition & 1 deletion pysetup/spec_builders/whisk.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ def hardcoded_custom_type_dep_constants(cls, spec_object) -> str:
@classmethod
def hardcoded_ssz_dep_constants(cls) -> Dict[str, str]:
constants = {
'EXECUTION_PAYLOAD_INDEX': 'GeneralizedIndex(41)',
'EXECUTION_PAYLOAD_GINDEX': 'GeneralizedIndex(41)',
}
return {**super().hardcoded_ssz_dep_constants(), **constants}
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ def _get_class_info_from_source(source: str) -> Tuple[str, Optional[str]]:
base = class_def.bases[0]
if isinstance(base, ast.Name):
parent_class = base.id
elif isinstance(base, ast.Subscript):
parent_class = base.value.id
else:
# NOTE: SSZ definition derives from earlier phase...
# e.g. `phase0.SignedBeaconBlock`
Expand Down
11 changes: 7 additions & 4 deletions specs/altair/light-client/full-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def create_light_client_bootstrap(state: BeaconState,
return LightClientBootstrap(
header=block_to_light_client_header(block),
current_sync_committee=state.current_sync_committee,
current_sync_committee_branch=compute_merkle_proof(state, CURRENT_SYNC_COMMITTEE_INDEX),
current_sync_committee_branch=CurrentSyncCommitteeBranch(
compute_merkle_proof(state, CURRENT_SYNC_COMMITTEE_GINDEX)),
)
```

Expand Down Expand Up @@ -122,7 +123,8 @@ def create_light_client_update(state: BeaconState,
# `next_sync_committee` is only useful if the message is signed by the current sync committee
if update_attested_period == update_signature_period:
update.next_sync_committee = attested_state.next_sync_committee
update.next_sync_committee_branch = compute_merkle_proof(attested_state, NEXT_SYNC_COMMITTEE_INDEX)
update.next_sync_committee_branch = NextSyncCommitteeBranch(
compute_merkle_proof(attested_state, NEXT_SYNC_COMMITTEE_GINDEX))

# Indicate finality whenever possible
if finalized_block is not None:
Expand All @@ -131,7 +133,8 @@ def create_light_client_update(state: BeaconState,
assert hash_tree_root(update.finalized_header.beacon) == attested_state.finalized_checkpoint.root
else:
assert attested_state.finalized_checkpoint.root == Bytes32()
update.finality_branch = compute_merkle_proof(attested_state, FINALIZED_ROOT_INDEX)
update.finality_branch = FinalityBranch(
compute_merkle_proof(attested_state, FINALIZED_ROOT_GINDEX))

update.sync_aggregate = block.message.body.sync_aggregate
update.signature_slot = block.message.slot
Expand All @@ -158,7 +161,7 @@ def create_light_client_finality_update(update: LightClientUpdate) -> LightClien
)
```

Full nodes SHOULD provide the `LightClientFinalityUpdate` with the highest `attested_header.beacon.slot` (if multiple, highest `signature_slot`) as selected by fork choice, and SHOULD support a push mechanism to deliver new `LightClientFinalityUpdate` whenever `finalized_header` changes.
Full nodes SHOULD provide the `LightClientFinalityUpdate` with the highest `attested_header.beacon.slot` (if multiple, highest `signature_slot`) as selected by fork choice, and SHOULD support a push mechanism to deliver new `LightClientFinalityUpdate` whenever `finalized_header` changes. If that `LightClientFinalityUpdate` does not have supermajority (> 2/3) sync committee participation, a second `LightClientFinalityUpdate` SHOULD be delivered for the same `finalized_header` once supermajority participation is obtained.

### `create_light_client_optimistic_update`

Expand Down
2 changes: 1 addition & 1 deletion specs/altair/light-client/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ New global topics are added to provide light clients with the latest updates.
This topic is used to propagate the latest `LightClientFinalityUpdate` to light clients, allowing them to keep track of the latest `finalized_header`.

The following validations MUST pass before forwarding the `finality_update` on the network.
- _[IGNORE]_ The `finalized_header.beacon.slot` is greater than that of all previously forwarded `finality_update`s
- _[IGNORE]_ The `finalized_header.beacon.slot` is greater than that of all previously forwarded `finality_update`s, or it matches the highest previously forwarded slot and also has a `sync_aggregate` indicating supermajority (> 2/3) sync committee participation while the previously forwarded `finality_update` for that slot did not indicate supermajority
- _[IGNORE]_ The `finality_update` is received after the block at `signature_slot` was given enough time to propagate through the network -- i.e. validate that one-third of `finality_update.signature_slot` has transpired (`SECONDS_PER_SLOT / INTERVALS_PER_SLOT` seconds after the start of the slot, with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance)

For full nodes, the following validations MUST additionally pass before forwarding the `finality_update` on the network.
Expand Down
45 changes: 27 additions & 18 deletions specs/altair/light-client/sync-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Custom types](#custom-types)
- [Constants](#constants)
- [Preset](#preset)
- [Misc](#misc)
Expand Down Expand Up @@ -56,13 +57,21 @@ Additional documents describe how the light client sync protocol can be used:
- [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` |

## Constants

| Name | Value |
| - | - |
| `FINALIZED_ROOT_INDEX` | `get_generalized_index(BeaconState, 'finalized_checkpoint', 'root')` (= 105) |
| `CURRENT_SYNC_COMMITTEE_INDEX` | `get_generalized_index(BeaconState, 'current_sync_committee')` (= 54) |
| `NEXT_SYNC_COMMITTEE_INDEX` | `get_generalized_index(BeaconState, 'next_sync_committee')` (= 55) |
| `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

Expand Down Expand Up @@ -93,7 +102,7 @@ class LightClientBootstrap(Container):
header: LightClientHeader
# Current sync committee corresponding to `header.beacon.state_root`
current_sync_committee: SyncCommittee
current_sync_committee_branch: Vector[Bytes32, floorlog2(CURRENT_SYNC_COMMITTEE_INDEX)]
current_sync_committee_branch: CurrentSyncCommitteeBranch
```

### `LightClientUpdate`
Expand All @@ -104,10 +113,10 @@ class LightClientUpdate(Container):
attested_header: LightClientHeader
# Next sync committee corresponding to `attested_header.beacon.state_root`
next_sync_committee: SyncCommittee
next_sync_committee_branch: Vector[Bytes32, floorlog2(NEXT_SYNC_COMMITTEE_INDEX)]
next_sync_committee_branch: NextSyncCommitteeBranch
# Finalized header corresponding to `attested_header.beacon.state_root`
finalized_header: LightClientHeader
finality_branch: Vector[Bytes32, floorlog2(FINALIZED_ROOT_INDEX)]
finality_branch: FinalityBranch
# Sync committee aggregate signature
sync_aggregate: SyncAggregate
# Slot at which the aggregate signature was created (untrusted)
Expand All @@ -122,7 +131,7 @@ class LightClientFinalityUpdate(Container):
attested_header: LightClientHeader
# Finalized header corresponding to `attested_header.beacon.state_root`
finalized_header: LightClientHeader
finality_branch: Vector[Bytes32, floorlog2(FINALIZED_ROOT_INDEX)]
finality_branch: FinalityBranch
# Sync committee aggregate signature
sync_aggregate: SyncAggregate
# Slot at which the aggregate signature was created (untrusted)
Expand Down Expand Up @@ -174,14 +183,14 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool:

```python
def is_sync_committee_update(update: LightClientUpdate) -> bool:
return update.next_sync_committee_branch != [Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))]
return update.next_sync_committee_branch != NextSyncCommitteeBranch()
```

### `is_finality_update`

```python
def is_finality_update(update: LightClientUpdate) -> bool:
return update.finality_branch != [Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))]
return update.finality_branch != FinalityBranch()
```

### `is_better_update`
Expand Down Expand Up @@ -286,8 +295,8 @@ def initialize_light_client_store(trusted_block_root: Root,
assert is_valid_merkle_branch(
leaf=hash_tree_root(bootstrap.current_sync_committee),
branch=bootstrap.current_sync_committee_branch,
depth=floorlog2(CURRENT_SYNC_COMMITTEE_INDEX),
index=get_subtree_index(CURRENT_SYNC_COMMITTEE_INDEX),
depth=floorlog2(CURRENT_SYNC_COMMITTEE_GINDEX),
index=get_subtree_index(CURRENT_SYNC_COMMITTEE_GINDEX),
root=bootstrap.header.beacon.state_root,
)

Expand Down Expand Up @@ -358,8 +367,8 @@ def validate_light_client_update(store: LightClientStore,
assert is_valid_merkle_branch(
leaf=finalized_root,
branch=update.finality_branch,
depth=floorlog2(FINALIZED_ROOT_INDEX),
index=get_subtree_index(FINALIZED_ROOT_INDEX),
depth=floorlog2(FINALIZED_ROOT_GINDEX),
index=get_subtree_index(FINALIZED_ROOT_GINDEX),
root=update.attested_header.beacon.state_root,
)

Expand All @@ -373,8 +382,8 @@ def validate_light_client_update(store: LightClientStore,
assert is_valid_merkle_branch(
leaf=hash_tree_root(update.next_sync_committee),
branch=update.next_sync_committee_branch,
depth=floorlog2(NEXT_SYNC_COMMITTEE_INDEX),
index=get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX),
depth=floorlog2(NEXT_SYNC_COMMITTEE_GINDEX),
index=get_subtree_index(NEXT_SYNC_COMMITTEE_GINDEX),
root=update.attested_header.beacon.state_root,
)

Expand Down Expand Up @@ -493,7 +502,7 @@ def process_light_client_finality_update(store: LightClientStore,
update = LightClientUpdate(
attested_header=finality_update.attested_header,
next_sync_committee=SyncCommittee(),
next_sync_committee_branch=[Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))],
next_sync_committee_branch=NextSyncCommitteeBranch(),
finalized_header=finality_update.finalized_header,
finality_branch=finality_update.finality_branch,
sync_aggregate=finality_update.sync_aggregate,
Expand All @@ -512,9 +521,9 @@ def process_light_client_optimistic_update(store: LightClientStore,
update = LightClientUpdate(
attested_header=optimistic_update.attested_header,
next_sync_committee=SyncCommittee(),
next_sync_committee_branch=[Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))],
next_sync_committee_branch=NextSyncCommitteeBranch(),
finalized_header=LightClientHeader(),
finality_branch=[Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))],
finality_branch=FinalityBranch(),
sync_aggregate=optimistic_update.sync_aggregate,
signature_slot=optimistic_update.signature_slot,
)
Expand Down
2 changes: 1 addition & 1 deletion specs/capella/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def is_partially_withdrawable_validator(validator: Validator, balance: Gwei) ->

### Epoch processing

*Note*: The function `process_historical_summaries_update` replaces `process_historical_roots_update` in Bellatrix.
*Note*: The function `process_historical_summaries_update` replaces `process_historical_roots_update` in Capella.

```python
def process_epoch(state: BeaconState) -> None:
Expand Down
5 changes: 3 additions & 2 deletions specs/capella/light-client/full-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ def block_to_light_client_header(block: SignedBeaconBlock) -> LightClientHeader:
transactions_root=hash_tree_root(payload.transactions),
withdrawals_root=hash_tree_root(payload.withdrawals),
)
execution_branch = compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_INDEX)
execution_branch = ExecutionBranch(
compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_GINDEX))
else:
# Note that during fork transitions, `finalized_header` may still point to earlier forks.
# While Bellatrix blocks also contain an `ExecutionPayload` (minus `withdrawals_root`),
# it was not included in the corresponding light client data. To ensure compatibility
# with legacy data going through `upgrade_lc_header_to_capella`, leave out execution data.
execution_header = ExecutionPayloadHeader()
execution_branch = [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))]
execution_branch = ExecutionBranch()

return LightClientHeader(
beacon=BeaconBlockHeader(
Expand Down
17 changes: 12 additions & 5 deletions specs/capella/light-client/sync-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Custom types](#custom-types)
- [Constants](#constants)
- [Containers](#containers)
- [Modified `LightClientHeader`](#modified-lightclientheader)
Expand All @@ -27,11 +28,17 @@ 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 |
| - | - | - |
| `ExecutionBranch` | `Vector[Bytes32, floorlog2(EXECUTION_PAYLOAD_GINDEX)]` | Merkle branch of `execution_payload` within `BeaconBlockBody` |

## Constants

| Name | Value |
| - | - |
| `EXECUTION_PAYLOAD_INDEX` | `get_generalized_index(BeaconBlockBody, 'execution_payload')` (= 25) |
| `EXECUTION_PAYLOAD_GINDEX` | `get_generalized_index(BeaconBlockBody, 'execution_payload')` (= 25) |

## Containers

Expand All @@ -43,7 +50,7 @@ class LightClientHeader(Container):
beacon: BeaconBlockHeader
# Execution payload header corresponding to `beacon.body_root` (from Capella onward)
execution: ExecutionPayloadHeader
execution_branch: Vector[Bytes32, floorlog2(EXECUTION_PAYLOAD_INDEX)]
execution_branch: ExecutionBranch
```

## Helper functions
Expand All @@ -69,14 +76,14 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool:
if epoch < CAPELLA_FORK_EPOCH:
return (
header.execution == ExecutionPayloadHeader()
and header.execution_branch == [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))]
and header.execution_branch == ExecutionBranch()
)

return is_valid_merkle_branch(
leaf=get_lc_execution_root(header),
branch=header.execution_branch,
depth=floorlog2(EXECUTION_PAYLOAD_INDEX),
index=get_subtree_index(EXECUTION_PAYLOAD_INDEX),
depth=floorlog2(EXECUTION_PAYLOAD_GINDEX),
index=get_subtree_index(EXECUTION_PAYLOAD_GINDEX),
root=header.beacon.body_root,
)
```
5 changes: 3 additions & 2 deletions specs/deneb/light-client/full-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ def block_to_light_client_header(block: SignedBeaconBlock) -> LightClientHeader:
execution_header.blob_gas_used = payload.blob_gas_used
execution_header.excess_blob_gas = payload.excess_blob_gas

execution_branch = compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_INDEX)
execution_branch = ExecutionBranch(
compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_GINDEX))
else:
# Note that during fork transitions, `finalized_header` may still point to earlier forks.
# While Bellatrix blocks also contain an `ExecutionPayload` (minus `withdrawals_root`),
# it was not included in the corresponding light client data. To ensure compatibility
# with legacy data going through `upgrade_lc_header_to_capella`, leave out execution data.
execution_header = ExecutionPayloadHeader()
execution_branch = [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))]
execution_branch = ExecutionBranch()

return LightClientHeader(
beacon=BeaconBlockHeader(
Expand Down
6 changes: 3 additions & 3 deletions specs/deneb/light-client/sync-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool:
if epoch < CAPELLA_FORK_EPOCH:
return (
header.execution == ExecutionPayloadHeader()
and header.execution_branch == [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))]
and header.execution_branch == ExecutionBranch()
)

return is_valid_merkle_branch(
leaf=get_lc_execution_root(header),
branch=header.execution_branch,
depth=floorlog2(EXECUTION_PAYLOAD_INDEX),
index=get_subtree_index(EXECUTION_PAYLOAD_INDEX),
depth=floorlog2(EXECUTION_PAYLOAD_GINDEX),
index=get_subtree_index(EXECUTION_PAYLOAD_GINDEX),
root=header.beacon.body_root,
)
```
Loading

0 comments on commit 696d443

Please sign in to comment.