Fix python execution 2

This commit is contained in:
Potuz 2024-07-02 17:30:59 -03:00
parent 2a43ce54d6
commit 4500eabf8c
3 changed files with 61 additions and 42 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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)