mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-03-01 18:50:35 +00:00
Fix python execution 2
This commit is contained in:
parent
2a43ce54d6
commit
4500eabf8c
@ -80,20 +80,20 @@ At any given slot, the status of the blockchain's head may be either
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `PTC_SIZE` | `uint64(2**9)` (=512) # (New in EIP-XXXX) |
|
||||
| `PTC_SIZE` | `uint64(2**9)` (=512) # (New in EIP-XXXX) |
|
||||
|
||||
### Domain types
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `DOMAIN_BEACON_BUILDER` | `DomainType('0x1B000000')` # (New in EIP-XXXX)|
|
||||
| `DOMAIN_PTC_ATTESTER` | `DomainType('0x0C000000')` # (New in EIP-XXXX)|
|
||||
| `DOMAIN_BEACON_BUILDER` | `DomainType('0x1B000000')` # (New in EIP-XXXX)|
|
||||
| `DOMAIN_PTC_ATTESTER` | `DomainType('0x0C000000')` # (New in EIP-XXXX)|
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_PAYLOAD_ATTESTATIONS` | `2**2` (= 4) # (New in EIP-XXXX) |
|
||||
| `MAX_PAYLOAD_ATTESTATIONS` | `2**2` (= 4) # (New in EIP-XXXX) |
|
||||
|
||||
## Containers
|
||||
|
||||
@ -186,8 +186,8 @@ class BeaconBlockBody(Container):
|
||||
# Removed blob_kzg_commitments [Removed in EIP-XXXX]
|
||||
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES]
|
||||
# PBS
|
||||
signed_execution_payload_header: SignedExecutionPayloadHeader # [New in EIP-XXXX]
|
||||
payload_attestations: List[PayloadAttestation, MAX_PAYLOAD_ATTESTATIONS] # [New in EIP-XXXX]
|
||||
signed_execution_payload_header: SignedExecutionPayloadHeader # [New in EIP-XXXX]
|
||||
payload_attestations: List[PayloadAttestation, MAX_PAYLOAD_ATTESTATIONS] # [New in EIP-XXXX]
|
||||
```
|
||||
|
||||
#### `ExecutionPayloadHeader`
|
||||
@ -262,9 +262,9 @@ class BeaconState(Container):
|
||||
pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT]
|
||||
pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT]
|
||||
# PBS
|
||||
latest_block_hash: Hash32 # [New in EIP-XXXX]
|
||||
latest_full_slot: Slot # [New in EIP-XXXX]
|
||||
latest_withdrawals_root: Root # [New in EIP-XXXX]
|
||||
latest_block_hash: Hash32 # [New in EIP-XXXX]
|
||||
latest_full_slot: Slot # [New in EIP-XXXX]
|
||||
latest_withdrawals_root: Root # [New in EIP-XXXX]
|
||||
```
|
||||
|
||||
## Helper functions
|
||||
@ -288,9 +288,12 @@ def bit_floor(n: uint64) -> uint64:
|
||||
#### `is_valid_indexed_payload_attestation`
|
||||
|
||||
```python
|
||||
def is_valid_indexed_payload_attestation(state: BeaconState, indexed_payload_attestation: IndexedPayloadAttestation) -> bool:
|
||||
def is_valid_indexed_payload_attestation(
|
||||
state: BeaconState,
|
||||
indexed_payload_attestation: IndexedPayloadAttestation) -> bool:
|
||||
"""
|
||||
Check if ``indexed_payload_attestation`` is not empty, has sorted and unique indices and has a valid aggregate signature.
|
||||
Check if ``indexed_payload_attestation`` is not empty, has sorted and unique indices and has
|
||||
a valid aggregate signature.
|
||||
"""
|
||||
# Verify the data is valid
|
||||
if indexed_payload_attestation.data.payload_status >= PAYLOAD_INVALID_STATUS:
|
||||
@ -402,8 +405,8 @@ The post-state corresponding to a pre-state `state` and a signed execution paylo
|
||||
```python
|
||||
def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
||||
process_block_header(state, block)
|
||||
process_withdrawals(state) # [Modified in EIP-XXXX]
|
||||
process_execution_payload_header(state, block) # [Modified in EIP-XXXX, removed process_execution_payload]
|
||||
process_withdrawals(state) # [Modified in EIP-XXXX]
|
||||
process_execution_payload_header(state, block) # [Modified in EIP-XXXX, removed process_execution_payload]
|
||||
process_randao(state, block.body)
|
||||
process_eth1_data(state, block.body)
|
||||
process_operations(state, block.body) # [Modified in EIP-XXXX]
|
||||
@ -415,7 +418,7 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
||||
|
||||
```python
|
||||
def process_withdrawals(state: BeaconState) -> None:
|
||||
## return early if the parent block was empty
|
||||
# return early if the parent block was empty
|
||||
if not is_parent_block_full(state):
|
||||
return
|
||||
|
||||
@ -448,7 +451,7 @@ def process_withdrawals(state: BeaconState) -> None:
|
||||
|
||||
```python
|
||||
def verify_execution_payload_header_signature(state: BeaconState,
|
||||
signed_header: SignedExecutionPayloadHeader) -> bool:
|
||||
signed_header: SignedExecutionPayloadHeader) -> bool:
|
||||
# Check the signature
|
||||
builder = state.validators[signed_header.message.builder_index]
|
||||
signing_root = compute_signing_root(signed_header.message, get_domain(state, DOMAIN_BEACON_BUILDER))
|
||||
@ -505,7 +508,7 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||
# Removed `process_deposit_request` in EIP-XXXX
|
||||
# Removed `process_withdrawal_request` in EIP-XXXX
|
||||
# Removed `process_consolidation_request` in EIP-XXXX
|
||||
for_ops(body.payload_attestations, process_payload_attestation) # [New in EIP-XXXX]
|
||||
for_ops(body.payload_attestations, process_payload_attestation) # [New in EIP-XXXX]
|
||||
```
|
||||
|
||||
##### Payload Attestations
|
||||
@ -518,17 +521,16 @@ def remove_flag(flags: ParticipationFlags, flag_index: int) -> ParticipationFlag
|
||||
|
||||
```python
|
||||
def process_payload_attestation(state: BeaconState, payload_attestation: PayloadAttestation) -> None:
|
||||
## Check that the attestation is for the parent beacon block
|
||||
# Check that the attestation is for the parent beacon block
|
||||
data = payload_attestation.data
|
||||
assert data.beacon_block_root == state.latest_block_header.parent_root
|
||||
## Check that the attestation is for the previous slot
|
||||
# Check that the attestation is for the previous slot
|
||||
assert data.slot + 1 == state.slot
|
||||
|
||||
#Verify signature
|
||||
# Verify signature
|
||||
indexed_payload_attestation = get_indexed_payload_attestation(state, data.slot, payload_attestation)
|
||||
assert is_valid_indexed_payload_attestation(state, indexed_payload_attestation)
|
||||
|
||||
ptc = get_ptc(state, data.slot)
|
||||
if state.slot % SLOTS_PER_EPOCH == 0:
|
||||
epoch_participation = state.previous_epoch_participation
|
||||
else:
|
||||
@ -548,7 +550,7 @@ def process_payload_attestation(state: BeaconState, payload_attestation: Payload
|
||||
epoch_participation[index] = remove_flag(epoch_participation[index], flag_index)
|
||||
proposer_penalty_numerator += get_base_reward(state, index) * weight
|
||||
# Penalize the proposer
|
||||
proposer_penalty = Gwei(2*proposer_penalty_numerator // proposer_reward_denominator)
|
||||
proposer_penalty = Gwei(2 * proposer_penalty_numerator // proposer_reward_denominator)
|
||||
decrease_balance(state, proposer_index, proposer_penalty)
|
||||
return
|
||||
|
||||
@ -568,7 +570,8 @@ def process_payload_attestation(state: BeaconState, payload_attestation: Payload
|
||||
#### New `verify_execution_payload_envelope_signature`
|
||||
|
||||
```python
|
||||
def verify_execution_payload_envelope_signature(state: BeaconState, signed_envelope: SignedExecutionPayloadEnvelope) -> bool:
|
||||
def verify_execution_payload_envelope_signature(
|
||||
state: BeaconState, signed_envelope: SignedExecutionPayloadEnvelope) -> bool:
|
||||
builder = state.validators[signed_envelope.message.builder_index]
|
||||
signing_root = compute_signing_root(signed_envelope.message, get_domain(state, DOMAIN_BEACON_BUILDER))
|
||||
return bls.Verify(builder.pubkey, signing_root, signed_envelope.signature)
|
||||
@ -578,7 +581,9 @@ def verify_execution_payload_envelope_signature(state: BeaconState, signed_envel
|
||||
*Note*: `process_execution_payload` is now an independent check in state transition. It is called when importing a signed execution payload proposed by the builder of the current slot.
|
||||
|
||||
```python
|
||||
def process_execution_payload(state: BeaconState, signed_envelope: SignedExecutionPayloadEnvelope, execution_engine: ExecutionEngine, verify = True) -> None:
|
||||
def process_execution_payload(state: BeaconState,
|
||||
signed_envelope: SignedExecutionPayloadEnvelope,
|
||||
execution_engine: ExecutionEngine, verify=True) -> None:
|
||||
# Verify signature
|
||||
if verify:
|
||||
assert verify_execution_payload_envelope_signature(state, signed_envelope)
|
||||
@ -607,7 +612,8 @@ def process_execution_payload(state: BeaconState, signed_envelope: SignedExecuti
|
||||
# Verify timestamp
|
||||
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
|
||||
# Verify the execution payload is valid
|
||||
versioned_hashes = [kzg_commitment_to_versioned_hash(commitment) for commitment in envelope.blob_kzg_commitments]
|
||||
versioned_hashes = [kzg_commitment_to_versioned_hash(commitment)
|
||||
for commitment in envelope.blob_kzg_commitments]
|
||||
assert execution_engine.verify_and_notify_new_payload(
|
||||
NewPayloadRequest(
|
||||
execution_payload=payload,
|
||||
|
@ -41,7 +41,8 @@ Builders can broadcast a payload bid for the current or the next slot's proposer
|
||||
After building the `header`, the builder obtains a `signature` of the header by using
|
||||
|
||||
```python
|
||||
def get_execution_payload_header_signature(state: BeaconState, header: ExecutionPayloadHeader, privkey: int) -> BLSSignature:
|
||||
def get_execution_payload_header_signature(
|
||||
state: BeaconState, header: ExecutionPayloadHeader, privkey: int) -> BLSSignature:
|
||||
domain = get_domain(state, DOMAIN_BEACON_BUILDER, compute_epoch_at_slot(header.slot))
|
||||
signing_root = compute_signing_root(header, domain)
|
||||
return bls.Sign(privkey, signing_root)
|
||||
@ -101,7 +102,8 @@ After setting these parameters, the builder should run `process_execution_payloa
|
||||
6. Set `state_root` to `hash_tree_root(state)`.
|
||||
After preparing the `envelope` the builder should sign the envelope using:
|
||||
```python
|
||||
def get_execution_payload_envelope_signature(state: BeaconState, envelope: ExecutionPayloadEnvelope, privkey: int) -> BLSSignature:
|
||||
def get_execution_payload_envelope_signature(
|
||||
state: BeaconState, envelope: ExecutionPayloadEnvelope, privkey: int) -> BLSSignature:
|
||||
domain = get_domain(state, DOMAIN_BEACON_BUILDER, compute_epoch_at_slot(state.slot))
|
||||
signing_root = compute_signing_root(envelope, domain)
|
||||
return bls.Sign(privkey, signing_root)
|
||||
|
@ -44,7 +44,7 @@ This is the modification of the fork choice accompanying the ePBS upgrade.
|
||||
|
||||
| Name | Value |
|
||||
| -------------------- | ----------- |
|
||||
| `PAYLOAD_TIMELY_THRESHOLD` | `PTC_SIZE/2` (=`uint64(256)`) |
|
||||
| `PAYLOAD_TIMELY_THRESHOLD` | `PTC_SIZE / 2` (=`uint64(256)`) |
|
||||
| `INTERVALS_PER_SLOT` | `4` # [modified in EIP-XXXX] |
|
||||
| `PROPOSER_SCORE_BOOST` | `20` # [modified in EIP-XXXX] |
|
||||
| `PAYLOAD_WITHHOLD_BOOST` | `40` |
|
||||
@ -100,9 +100,9 @@ class Store(object):
|
||||
unrealized_justified_checkpoint: Checkpoint
|
||||
unrealized_finalized_checkpoint: Checkpoint
|
||||
proposer_boost_root: Root
|
||||
payload_withhold_boost_root: Root # [New in EIP-XXXX]
|
||||
payload_withhold_boost_full: boolean # [New in EIP-XXXX]
|
||||
payload_reveal_boost_root: Root # [New in EIP-XXXX]
|
||||
payload_withhold_boost_root: Root # [New in EIP-XXXX]
|
||||
payload_withhold_boost_full: boolean # [New in EIP-XXXX]
|
||||
payload_reveal_boost_root: Root # [New in EIP-XXXX]
|
||||
equivocating_indices: Set[ValidatorIndex]
|
||||
blocks: Dict[Root, BeaconBlock] = field(default_factory=dict)
|
||||
block_states: Dict[Root, BeaconState] = field(default_factory=dict)
|
||||
@ -110,8 +110,8 @@ class Store(object):
|
||||
checkpoint_states: Dict[Checkpoint, BeaconState] = field(default_factory=dict)
|
||||
latest_messages: Dict[ValidatorIndex, LatestMessage] = field(default_factory=dict)
|
||||
unrealized_justifications: Dict[Root, Checkpoint] = field(default_factory=dict)
|
||||
execution_payload_states: Dict[Root, BeaconState] = field(default_factory=dict) # [New in EIP-XXXX]
|
||||
ptc_vote: Dict[Root, Vector[uint8, PTC_SIZE]] = field(default_factory=dict) # [New in EIP-XXXX]
|
||||
execution_payload_states: Dict[Root, BeaconState] = field(default_factory=dict) # [New in EIP-XXXX]
|
||||
ptc_vote: Dict[Root, Vector[uint8, PTC_SIZE]] = field(default_factory=dict) # [New in EIP-XXXX]
|
||||
```
|
||||
|
||||
### Modified `get_forkchoice_store`
|
||||
@ -132,9 +132,9 @@ def get_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock) -
|
||||
unrealized_justified_checkpoint=justified_checkpoint,
|
||||
unrealized_finalized_checkpoint=finalized_checkpoint,
|
||||
proposer_boost_root=proposer_boost_root,
|
||||
payload_withhold_boost_root=proposer_boost_root, # [New in EIP-XXXX]
|
||||
payload_withhold_boost_full=True, # [New in EIP-XXXX]
|
||||
payload_reveal_boost_root=proposer_boost_root, # [New in EIP-XXXX]
|
||||
payload_withhold_boost_root=proposer_boost_root, # [New in EIP-XXXX]
|
||||
payload_withhold_boost_full=True, # [New in EIP-XXXX]
|
||||
payload_reveal_boost_root=proposer_boost_root, # [New in EIP-XXXX]
|
||||
equivocating_indices=set(),
|
||||
blocks={anchor_root: copy(anchor_block)},
|
||||
block_states={anchor_root: copy(anchor_state)},
|
||||
@ -156,8 +156,9 @@ def notify_ptc_messages(store: Store, state: BeaconState, payload_attestations:
|
||||
for payload_attestation in payload_attestations:
|
||||
indexed_payload_attestation = get_indexed_payload_attestation(state, Slot(state.slot - 1), payload_attestation)
|
||||
for idx in indexed_payload_attestation.attesting_indices:
|
||||
on_payload_attestation_message(store, PayloadAttestationMessage(validator_index=idx,
|
||||
data=payload_attestation.data, signature= BLSSignature(), is_from_block=True))
|
||||
on_payload_attestation_message(store,
|
||||
PayloadAttestationMessage(validator_index=idx,
|
||||
data=payload_attestation.data, signature=BLSSignature(), is_from_block=True))
|
||||
```
|
||||
|
||||
### `is_payload_present`
|
||||
@ -333,19 +334,29 @@ def get_head(store: Store) -> ChildNode:
|
||||
children = [
|
||||
ChildNode(root=root, slot=block.slot, is_payload_present=present) for (root, block) in blocks.items()
|
||||
if block.parent_root == best_child.root and
|
||||
is_parent_node_full(store, block) == best_child.is_payload_present if root != store.justified_checkpoint.root
|
||||
for present in (True, False) if root in store.execution_payload_states or present == False
|
||||
is_parent_node_full(store, block) == best_child.is_payload_present if
|
||||
root != store.justified_checkpoint.root
|
||||
for present in (True, False) if root in store.execution_payload_states or not present
|
||||
]
|
||||
if len(children) == 0:
|
||||
return best_child
|
||||
# if we have children we consider the current head advanced as a possible head
|
||||
children += [ChildNode(root=best_child.root, slot=best_child.slot + 1, is_payload_present=best_child.is_payload_present)]
|
||||
children += [
|
||||
ChildNode(root=best_child.root, slot=best_child.slot + 1, is_payload_present=best_child.is_payload_present)
|
||||
]
|
||||
# Sort by latest attesting balance with ties broken lexicographically
|
||||
# Ties broken by favoring full blocks according to the PTC vote
|
||||
# Ties are then broken by favoring full blocks
|
||||
# Ties broken then by favoring higher slot numbers
|
||||
# Ties then broken by favoring block with lexicographically higher root
|
||||
new_best_child = max(children, key=lambda child: (get_weight(store, child), is_payload_present(store, child.root), child.is_payload_present, child.slot, child.root))
|
||||
new_best_child = max(children, key=lambda child: (
|
||||
get_weight(store, child),
|
||||
is_payload_present(store, child.root),
|
||||
child.is_payload_present,
|
||||
child.slot,
|
||||
child.root
|
||||
)
|
||||
)
|
||||
if new_best_child.root == best_child.root:
|
||||
return new_best_child
|
||||
best_child = new_best_child
|
||||
@ -402,7 +413,7 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
|
||||
# Add new state for this block to the store
|
||||
store.block_states[block_root] = state
|
||||
# Add a new PTC voting for this block to the store
|
||||
store.ptc_vote[block_root] = [PAYLOAD_ABSENT]*PTC_SIZE
|
||||
store.ptc_vote[block_root] = [PAYLOAD_ABSENT] * PTC_SIZE
|
||||
|
||||
# Notify the store about the payload_attestations in the block
|
||||
notify_ptc_messages(store, state, block.body.payload_attestations)
|
||||
|
Loading…
x
Reference in New Issue
Block a user