Reorder by processing seq
This commit is contained in:
parent
353bbb02a6
commit
db2c01a5f5
|
@ -70,20 +70,28 @@
|
||||||
- [New `process_pending_consolidations`](#new-process_pending_consolidations)
|
- [New `process_pending_consolidations`](#new-process_pending_consolidations)
|
||||||
- [Updated `process_effective_balance_updates`](#updated-process_effective_balance_updates)
|
- [Updated `process_effective_balance_updates`](#updated-process_effective_balance_updates)
|
||||||
- [Block processing](#block-processing)
|
- [Block processing](#block-processing)
|
||||||
|
- [Withdrawals](#withdrawals)
|
||||||
- [Updated `get_expected_withdrawals`](#updated-get_expected_withdrawals)
|
- [Updated `get_expected_withdrawals`](#updated-get_expected_withdrawals)
|
||||||
- [Updated `process_withdrawals`](#updated-process_withdrawals)
|
- [Updated `process_withdrawals`](#updated-process_withdrawals)
|
||||||
|
- [Execution payload](#execution-payload)
|
||||||
|
- [Modified `process_execution_payload`](#modified-process_execution_payload)
|
||||||
|
- [Operations](#operations)
|
||||||
- [Modified `process_operations`](#modified-process_operations)
|
- [Modified `process_operations`](#modified-process_operations)
|
||||||
|
- [Attestations](#attestations)
|
||||||
- [Modified `process_attestation`](#modified-process_attestation)
|
- [Modified `process_attestation`](#modified-process_attestation)
|
||||||
- [Deposits](#deposits)
|
- [Deposits](#deposits)
|
||||||
- [Updated `apply_deposit`](#updated--apply_deposit)
|
- [Updated `apply_deposit`](#updated--apply_deposit)
|
||||||
- [New `is_valid_deposit_signature`](#new-is_valid_deposit_signature)
|
- [New `is_valid_deposit_signature`](#new-is_valid_deposit_signature)
|
||||||
- [Modified `add_validator_to_registry`](#modified-add_validator_to_registry)
|
- [Modified `add_validator_to_registry`](#modified-add_validator_to_registry)
|
||||||
- [Updated `get_validator_from_deposit`](#updated-get_validator_from_deposit)
|
- [Updated `get_validator_from_deposit`](#updated-get_validator_from_deposit)
|
||||||
- [New `process_deposit_receipt`](#new-process_deposit_receipt)
|
- [Voluntary exits](#voluntary-exits)
|
||||||
- [New `process_execution_layer_withdrawal_request`](#new-process_execution_layer_withdrawal_request)
|
|
||||||
- [Modified `process_execution_payload`](#modified-process_execution_payload)
|
|
||||||
- [New `process_consolidation`](#new-process_consolidation)
|
|
||||||
- [Updated `process_voluntary_exit`](#updated-process_voluntary_exit)
|
- [Updated `process_voluntary_exit`](#updated-process_voluntary_exit)
|
||||||
|
- [Execution layer withdrawal requests](#execution-layer-withdrawal-requests)
|
||||||
|
- [New `process_execution_layer_withdrawal_request`](#new-process_execution_layer_withdrawal_request)
|
||||||
|
- [Deposit receipts](#deposit-receipts)
|
||||||
|
- [New `process_deposit_receipt`](#new-process_deposit_receipt)
|
||||||
|
- [Consolidations](#consolidations)
|
||||||
|
- [New `process_consolidation`](#new-process_consolidation)
|
||||||
- [Testing](#testing)
|
- [Testing](#testing)
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
@ -815,7 +823,9 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
process_sync_aggregate(state, block.body.sync_aggregate)
|
process_sync_aggregate(state, block.body.sync_aggregate)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Updated `get_expected_withdrawals`
|
#### Withdrawals
|
||||||
|
|
||||||
|
##### Updated `get_expected_withdrawals`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], uint64]:
|
def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], uint64]:
|
||||||
|
@ -871,7 +881,7 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal],
|
||||||
return withdrawals, partial_withdrawals_count
|
return withdrawals, partial_withdrawals_count
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Updated `process_withdrawals`
|
##### Updated `process_withdrawals`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
|
def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
|
||||||
|
@ -903,8 +913,60 @@ def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
|
||||||
state.next_withdrawal_validator_index = next_validator_index
|
state.next_withdrawal_validator_index = next_validator_index
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Execution payload
|
||||||
|
|
||||||
#### Modified `process_operations`
|
##### Modified `process_execution_payload`
|
||||||
|
|
||||||
|
*Note*: The function `process_execution_payload` is modified to use the new `ExecutionPayloadHeader` type.
|
||||||
|
|
||||||
|
```python
|
||||||
|
def process_execution_payload(state: BeaconState, body: BeaconBlockBody, execution_engine: ExecutionEngine) -> None:
|
||||||
|
payload = body.execution_payload
|
||||||
|
|
||||||
|
# Verify consistency of the parent hash with respect to the previous execution payload header
|
||||||
|
assert payload.parent_hash == state.latest_execution_payload_header.block_hash
|
||||||
|
# Verify prev_randao
|
||||||
|
assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state))
|
||||||
|
# Verify timestamp
|
||||||
|
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
|
||||||
|
# Verify commitments are under limit
|
||||||
|
assert len(body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
|
||||||
|
# Verify the execution payload is valid
|
||||||
|
versioned_hashes = [kzg_commitment_to_versioned_hash(commitment) for commitment in body.blob_kzg_commitments]
|
||||||
|
assert execution_engine.verify_and_notify_new_payload(
|
||||||
|
NewPayloadRequest(
|
||||||
|
execution_payload=payload,
|
||||||
|
versioned_hashes=versioned_hashes,
|
||||||
|
parent_beacon_block_root=state.latest_block_header.parent_root,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Cache execution payload header
|
||||||
|
state.latest_execution_payload_header = ExecutionPayloadHeader(
|
||||||
|
parent_hash=payload.parent_hash,
|
||||||
|
fee_recipient=payload.fee_recipient,
|
||||||
|
state_root=payload.state_root,
|
||||||
|
receipts_root=payload.receipts_root,
|
||||||
|
logs_bloom=payload.logs_bloom,
|
||||||
|
prev_randao=payload.prev_randao,
|
||||||
|
block_number=payload.block_number,
|
||||||
|
gas_limit=payload.gas_limit,
|
||||||
|
gas_used=payload.gas_used,
|
||||||
|
timestamp=payload.timestamp,
|
||||||
|
extra_data=payload.extra_data,
|
||||||
|
base_fee_per_gas=payload.base_fee_per_gas,
|
||||||
|
block_hash=payload.block_hash,
|
||||||
|
transactions_root=hash_tree_root(payload.transactions),
|
||||||
|
withdrawals_root=hash_tree_root(payload.withdrawals),
|
||||||
|
blob_gas_used=payload.blob_gas_used,
|
||||||
|
excess_blob_gas=payload.excess_blob_gas,
|
||||||
|
deposit_receipts_root=hash_tree_root(payload.deposit_receipts), # [New in Electra:EIP6110]
|
||||||
|
withdrawal_requests_root=hash_tree_root(payload.withdrawal_requests), # [New in Electra:EIP7002:EIP7251]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Operations
|
||||||
|
|
||||||
|
##### Modified `process_operations`
|
||||||
|
|
||||||
*Note*: The function `process_operations` is modified to support all of the new functionality in Electra.
|
*Note*: The function `process_operations` is modified to support all of the new functionality in Electra.
|
||||||
|
|
||||||
|
@ -934,7 +996,9 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||||
for_ops(body.consolidations, process_consolidation) # [New in Electra:EIP7251]
|
for_ops(body.consolidations, process_consolidation) # [New in Electra:EIP7251]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Modified `process_attestation`
|
##### Attestations
|
||||||
|
|
||||||
|
###### Modified `process_attestation`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||||
|
@ -981,7 +1045,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||||
|
|
||||||
##### Deposits
|
##### Deposits
|
||||||
|
|
||||||
##### Updated `apply_deposit`
|
###### Updated `apply_deposit`
|
||||||
|
|
||||||
*NOTE*: `process_deposit` is updated with a new definition of `apply_deposit`.
|
*NOTE*: `process_deposit` is updated with a new definition of `apply_deposit`.
|
||||||
|
|
||||||
|
@ -1012,7 +1076,7 @@ def apply_deposit(state: BeaconState,
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
##### New `is_valid_deposit_signature`
|
###### New `is_valid_deposit_signature`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def is_valid_deposit_signature(pubkey: BLSPubkey,
|
def is_valid_deposit_signature(pubkey: BLSPubkey,
|
||||||
|
@ -1029,7 +1093,7 @@ def is_valid_deposit_signature(pubkey: BLSPubkey,
|
||||||
return bls.Verify(pubkey, signing_root, signature)
|
return bls.Verify(pubkey, signing_root, signature)
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Modified `add_validator_to_registry`
|
###### Modified `add_validator_to_registry`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def add_validator_to_registry(state: BeaconState,
|
def add_validator_to_registry(state: BeaconState,
|
||||||
|
@ -1046,7 +1110,7 @@ def add_validator_to_registry(state: BeaconState,
|
||||||
state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=amount)) # [New in Electra:EIP7251]
|
state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=amount)) # [New in Electra:EIP7251]
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Updated `get_validator_from_deposit`
|
###### Updated `get_validator_from_deposit`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes32) -> Validator:
|
def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes32) -> Validator:
|
||||||
|
@ -1061,26 +1125,34 @@ def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes3
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
##### New `process_deposit_receipt`
|
##### Voluntary exits
|
||||||
|
###### Updated `process_voluntary_exit`
|
||||||
*Note*: This function is new in Electra:EIP6110.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_deposit_receipt(state: BeaconState, deposit_receipt: DepositReceipt) -> None:
|
def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
|
||||||
# Set deposit receipt start index
|
voluntary_exit = signed_voluntary_exit.message
|
||||||
if state.deposit_receipts_start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX:
|
validator = state.validators[voluntary_exit.validator_index]
|
||||||
state.deposit_receipts_start_index = deposit_receipt.index
|
# Verify the validator is active
|
||||||
|
assert is_active_validator(validator, get_current_epoch(state))
|
||||||
apply_deposit(
|
# Verify exit has not been initiated
|
||||||
state=state,
|
assert validator.exit_epoch == FAR_FUTURE_EPOCH
|
||||||
pubkey=deposit_receipt.pubkey,
|
# Exits must specify an epoch when they become valid; they are not valid before then
|
||||||
withdrawal_credentials=deposit_receipt.withdrawal_credentials,
|
assert get_current_epoch(state) >= voluntary_exit.epoch
|
||||||
amount=deposit_receipt.amount,
|
# Verify the validator has been active long enough
|
||||||
signature=deposit_receipt.signature,
|
assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
|
||||||
)
|
# Only exit validator if it has no pending withdrawals in the queue
|
||||||
|
assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in Electra:EIP7251]
|
||||||
|
# Verify signature
|
||||||
|
domain = compute_domain(DOMAIN_VOLUNTARY_EXIT, CAPELLA_FORK_VERSION, state.genesis_validators_root)
|
||||||
|
signing_root = compute_signing_root(voluntary_exit, domain)
|
||||||
|
assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
|
||||||
|
# Initiate exit
|
||||||
|
initiate_validator_exit(state, voluntary_exit.validator_index)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### New `process_execution_layer_withdrawal_request`
|
##### Execution layer withdrawal requests
|
||||||
|
|
||||||
|
###### New `process_execution_layer_withdrawal_request`
|
||||||
|
|
||||||
*Note*: This function is new in Electra following EIP-7002 and EIP-7251.
|
*Note*: This function is new in Electra following EIP-7002 and EIP-7251.
|
||||||
|
|
||||||
|
@ -1147,56 +1219,30 @@ def process_execution_layer_withdrawal_request(
|
||||||
))
|
))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Modified `process_execution_payload`
|
##### Deposit receipts
|
||||||
|
|
||||||
*Note*: The function `process_execution_payload` is modified to use the new `ExecutionPayloadHeader` type.
|
###### New `process_deposit_receipt`
|
||||||
|
|
||||||
|
*Note*: This function is new in Electra:EIP6110.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_execution_payload(state: BeaconState, body: BeaconBlockBody, execution_engine: ExecutionEngine) -> None:
|
def process_deposit_receipt(state: BeaconState, deposit_receipt: DepositReceipt) -> None:
|
||||||
payload = body.execution_payload
|
# Set deposit receipt start index
|
||||||
|
if state.deposit_receipts_start_index == UNSET_DEPOSIT_RECEIPTS_START_INDEX:
|
||||||
|
state.deposit_receipts_start_index = deposit_receipt.index
|
||||||
|
|
||||||
# Verify consistency of the parent hash with respect to the previous execution payload header
|
apply_deposit(
|
||||||
assert payload.parent_hash == state.latest_execution_payload_header.block_hash
|
state=state,
|
||||||
# Verify prev_randao
|
pubkey=deposit_receipt.pubkey,
|
||||||
assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state))
|
withdrawal_credentials=deposit_receipt.withdrawal_credentials,
|
||||||
# Verify timestamp
|
amount=deposit_receipt.amount,
|
||||||
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
|
signature=deposit_receipt.signature,
|
||||||
# Verify commitments are under limit
|
|
||||||
assert len(body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
|
|
||||||
# Verify the execution payload is valid
|
|
||||||
versioned_hashes = [kzg_commitment_to_versioned_hash(commitment) for commitment in body.blob_kzg_commitments]
|
|
||||||
assert execution_engine.verify_and_notify_new_payload(
|
|
||||||
NewPayloadRequest(
|
|
||||||
execution_payload=payload,
|
|
||||||
versioned_hashes=versioned_hashes,
|
|
||||||
parent_beacon_block_root=state.latest_block_header.parent_root,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# Cache execution payload header
|
|
||||||
state.latest_execution_payload_header = ExecutionPayloadHeader(
|
|
||||||
parent_hash=payload.parent_hash,
|
|
||||||
fee_recipient=payload.fee_recipient,
|
|
||||||
state_root=payload.state_root,
|
|
||||||
receipts_root=payload.receipts_root,
|
|
||||||
logs_bloom=payload.logs_bloom,
|
|
||||||
prev_randao=payload.prev_randao,
|
|
||||||
block_number=payload.block_number,
|
|
||||||
gas_limit=payload.gas_limit,
|
|
||||||
gas_used=payload.gas_used,
|
|
||||||
timestamp=payload.timestamp,
|
|
||||||
extra_data=payload.extra_data,
|
|
||||||
base_fee_per_gas=payload.base_fee_per_gas,
|
|
||||||
block_hash=payload.block_hash,
|
|
||||||
transactions_root=hash_tree_root(payload.transactions),
|
|
||||||
withdrawals_root=hash_tree_root(payload.withdrawals),
|
|
||||||
blob_gas_used=payload.blob_gas_used,
|
|
||||||
excess_blob_gas=payload.excess_blob_gas,
|
|
||||||
deposit_receipts_root=hash_tree_root(payload.deposit_receipts), # [New in Electra:EIP6110]
|
|
||||||
withdrawal_requests_root=hash_tree_root(payload.withdrawal_requests), # [New in Electra:EIP7002:EIP7251]
|
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### New `process_consolidation`
|
##### Consolidations
|
||||||
|
|
||||||
|
###### New `process_consolidation`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_consolidation(state: BeaconState, signed_consolidation: SignedConsolidation) -> None:
|
def process_consolidation(state: BeaconState, signed_consolidation: SignedConsolidation) -> None:
|
||||||
|
@ -1245,30 +1291,6 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol
|
||||||
))
|
))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Updated `process_voluntary_exit`
|
|
||||||
|
|
||||||
```python
|
|
||||||
def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None:
|
|
||||||
voluntary_exit = signed_voluntary_exit.message
|
|
||||||
validator = state.validators[voluntary_exit.validator_index]
|
|
||||||
# Verify the validator is active
|
|
||||||
assert is_active_validator(validator, get_current_epoch(state))
|
|
||||||
# Verify exit has not been initiated
|
|
||||||
assert validator.exit_epoch == FAR_FUTURE_EPOCH
|
|
||||||
# Exits must specify an epoch when they become valid; they are not valid before then
|
|
||||||
assert get_current_epoch(state) >= voluntary_exit.epoch
|
|
||||||
# Verify the validator has been active long enough
|
|
||||||
assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
|
|
||||||
# Only exit validator if it has no pending withdrawals in the queue
|
|
||||||
assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in Electra:EIP7251]
|
|
||||||
# Verify signature
|
|
||||||
domain = compute_domain(DOMAIN_VOLUNTARY_EXIT, CAPELLA_FORK_VERSION, state.genesis_validators_root)
|
|
||||||
signing_root = compute_signing_root(voluntary_exit, domain)
|
|
||||||
assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature)
|
|
||||||
# Initiate exit
|
|
||||||
initiate_validator_exit(state, voluntary_exit.validator_index)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
*Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Electra testing only.
|
*Note*: The function `initialize_beacon_state_from_eth1` is modified for pure Electra testing only.
|
||||||
|
|
Loading…
Reference in New Issue