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

Blobgas computation in CL #3813

Open
wants to merge 24 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4c29b0b
specify the max blobs per block when building a payload
ralexstokes Jun 12, 2024
71f2912
specify the maximum number of blobs for each payload
ralexstokes Jun 12, 2024
1aa7488
update spec builder for electra execution engine
ralexstokes Jun 12, 2024
d658c86
EIP-7549: Append new `committee_bits` field to end of `Attestation`
etan-status May 16, 2024
97dfba2
Update polynomial-commitments-sampling.md - Fix dead link
b-wagn Jun 13, 2024
29c8275
Update specs/_features/eip7594/polynomial-commitments-sampling.md
b-wagn Jun 13, 2024
5a7f74c
bump version to `1.5.0-alpha.3`
hwwhww Jun 13, 2024
053103d
Switch spec to MAX_EFFECTIVE_BALANCE_ELECTRA
mkalinin May 31, 2024
3e09a34
Update tests
mkalinin May 31, 2024
43d2089
Fix lint
mkalinin May 31, 2024
3960883
Applied suggestions by @hwwhww
mkalinin Jun 3, 2024
4b1c429
Apply suggestion from @hwwhww
mkalinin Jun 14, 2024
b3328ac
Fix tests and remove duplicate `_WITHDRAWAL_PREFIX` definition
hwwhww Jun 14, 2024
2eda0a9
extend test for eip7594
b-wagn Jun 14, 2024
91e23da
extend test for coset_fft
b-wagn Jun 14, 2024
172e27f
remove trailing whitespaces
b-wagn Jun 14, 2024
4fd2be8
fix typo
hwwhww Jun 14, 2024
63813eb
Remove `assert len(missing_cell_indices) != 0` check
hwwhww Jun 14, 2024
b0ac4cb
Bump remerkleable to `v0.1.28`
etan-status Jun 16, 2024
c2b9858
Add Electra merkle proof test vectors
hwwhww May 13, 2024
3c93ea2
Blob base fee computation in CL
dankrad Jun 24, 2024
709a424
Merge branch 'dev' into dankrad-blobgas-in-cl
dankrad Jun 24, 2024
c499d3a
Update specs/electra/beacon-chain.md
dankrad Jun 25, 2024
35fd6c6
Fix 8.49 computation
dankrad Jun 25, 2024
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
49 changes: 43 additions & 6 deletions pysetup/spec_builders/electra.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,53 @@ class ElectraSpecBuilder(BaseSpecBuilder):

@classmethod
def imports(cls, preset_name: str):
return f'''
return f"""
from eth2spec.deneb import {preset_name} as deneb
'''
"""

## TODO: deal with changed gindices
@classmethod
def execution_engine_cls(cls) -> str:
return """
class NoopExecutionEngine(ExecutionEngine):

def notify_new_payload(self: ExecutionEngine,
execution_payload: ExecutionPayload,
parent_beacon_block_root: Root,
max_blobs_per_block: uint64) -> bool:
return True

def notify_forkchoice_updated(self: ExecutionEngine,
head_block_hash: Hash32,
safe_block_hash: Hash32,
finalized_block_hash: Hash32,
payload_attributes: Optional[PayloadAttributes]) -> Optional[PayloadId]:
pass

def get_payload(self: ExecutionEngine, payload_id: PayloadId) -> GetPayloadResponse:
# pylint: disable=unused-argument
raise NotImplementedError("no default block production")

def is_valid_block_hash(self: ExecutionEngine,
execution_payload: ExecutionPayload,
parent_beacon_block_root: Root) -> bool:
return True

def is_valid_versioned_hashes(self: ExecutionEngine, new_payload_request: NewPayloadRequest) -> bool:
return True

def verify_and_notify_new_payload(self: ExecutionEngine,
new_payload_request: NewPayloadRequest) -> bool:
return True


EXECUTION_ENGINE = NoopExecutionEngine()"""

## TODO: deal with changed gindices

@classmethod
def hardcoded_ssz_dep_constants(cls) -> Dict[str, str]:
return {
'FINALIZED_ROOT_GINDEX': 'GeneralizedIndex(169)',
'CURRENT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(86)',
'NEXT_SYNC_COMMITTEE_GINDEX': 'GeneralizedIndex(87)',
"FINALIZED_ROOT_GINDEX": "GeneralizedIndex(169)",
"CURRENT_SYNC_COMMITTEE_GINDEX": "GeneralizedIndex(86)",
"NEXT_SYNC_COMMITTEE_GINDEX": "GeneralizedIndex(87)",
}
106 changes: 104 additions & 2 deletions specs/electra/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@
- [New `compute_consolidation_epoch_and_update_churn`](#new-compute_consolidation_epoch_and_update_churn)
- [Updated `slash_validator`](#updated-slash_validator)
- [Beacon chain state transition function](#beacon-chain-state-transition-function)
- [Execution engine](#execution-engine)
- [Request data](#request-data)
- [Engine APIs](#engine-apis)
- [Modified `notify_new_payload`](#modified-notify_new_payload)
- [Modified `verify_and_notify_new_payload`](#modified-verify_and_notify_new_payload)
- [Epoch processing](#epoch-processing)
- [Updated `process_epoch`](#updated-process_epoch)
- [Updated `process_registry_updates`](#updated--process_registry_updates)
Expand Down Expand Up @@ -180,6 +185,13 @@ The following values are (non-configurable) constants used throughout the specif
| - | - | - |
| `MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP` | `uint64(2**3)` (= 8)| *[New in Electra:EIP7002]* Maximum number of pending partial withdrawals to process per payload |

### Blobs

| Name | Value | Description |
| - | - | - |
| `TARGET_BLOBS_PER_BLOCK` | `uint64(3)` | *[New in Electra]* Target number of blobs per block |


## Configuration

### Validator cycle
Expand Down Expand Up @@ -332,7 +344,7 @@ class ExecutionPayload(Container):
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
blob_gas_used: uint64
excess_blob_gas: uint64
excess_blob_gas: uint64 # [Deprecated in Electra: compute blob gas in CL]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this field can be repurposed and renamed to base_fee_per_blob_gas, this is to make EL block self-contained in terms of execution which is required for optimistic sync (in an edge case but still). Then, this parameter must be verified in the process_execution_payload:

assert payload.base_fee_per_blob_gas == get_base_fee_per_blob_gas(state)

deposit_requests: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD] # [New in Electra:EIP6110]
# [New in Electra:EIP7002:EIP7251]
withdrawal_requests: List[WithdrawalRequest, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD]
Expand Down Expand Up @@ -362,7 +374,7 @@ class ExecutionPayloadHeader(Container):
transactions_root: Root
withdrawals_root: Root
blob_gas_used: uint64
excess_blob_gas: uint64
excess_blob_gas: uint64 # [Deprecated in Electra: compute blob gas in CL]
deposit_requests_root: Root # [New in Electra:EIP6110]
withdrawal_requests_root: Root # [New in Electra:EIP7002:EIP7251]
consolidation_requests_root: Root # [New in Electra:EIP7251]
Expand Down Expand Up @@ -423,10 +435,50 @@ class BeaconState(Container):
# [New in Electra:EIP7251]
pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT]
pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251]
# [New in Electra: compute blob gas in CL]
excess_blob_gas: uint64
base_fee_per_blob_gas: uint64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to keep this parameter to be in the state as it can be easily computed given the state?

```

## Helper functions

### Blob gas fee computation

#### `fake_exponential`

```python
def fake_exponential(factor: int, numerator: int, denominator: int) -> int:
i = 1
output = 0
numerator_accum = factor * denominator
while numerator_accum > 0:
output += numerator_accum
numerator_accum = (numerator_accum * numerator) // (denominator * i)
i += 1
return output // denominator
```

#### `fake_exponential`
dankrad marked this conversation as resolved.
Show resolved Hide resolved

```python
def get_blob_base_fee_update_fraction(max_blobs: int, target_blobs:int)) -> int:
max_excess_per_block = (max_blobs - target_blobs) * BLOB_GAS_PER_BLOB
# 1 / ln(9 / 8) ~= 8.49 = 849 / 1000
dankrad marked this conversation as resolved.
Show resolved Hide resolved
return max_excess_per_block * 849 // 1000
```


#### `get_base_fee_per_blob_gas`

```python
def get_base_fee_per_blob_gas(state: BeaconState) -> int:
return fake_exponential(
MIN_BASE_FEE_PER_BLOB_GAS,
state.excess_blob_gas,
get_blob_base_fee_update_fraction(MAX_BLOBS, TARGET_BLOBS_PER_BLOCK)
)
```

### Predicates

#### Updated `compute_proposer_index`
Expand Down Expand Up @@ -789,6 +841,56 @@ def slash_validator(state: BeaconState,

## Beacon chain state transition function

### Execution engine

#### Request data

#### Engine APIs

##### Modified `notify_new_payload`

*Note*: The function `notify_new_payload` is modified to include the blob gas fee.

```python
def notify_new_payload(self: ExecutionEngine,
execution_payload: ExecutionPayload,
parent_beacon_block_root: Root,
base_fee_per_blob_gas: uint64) -> bool:
"""
Return ``True`` if and only if ``execution_payload`` is valid with respect to ``self.execution_state``.
"""
...
```

##### Modified `verify_and_notify_new_payload`

```python
def verify_and_notify_new_payload(self: ExecutionEngine,
state: BeaconState,
new_payload_request: NewPayloadRequest) -> bool:
"""
Return ``True`` if and only if ``new_payload_request`` is valid with respect to ``self.execution_state``.
"""
execution_payload = new_payload_request.execution_payload
parent_beacon_block_root = new_payload_request.parent_beacon_block_root

if not self.is_valid_block_hash(execution_payload, parent_beacon_block_root):
return False

if not self.is_valid_versioned_hashes(new_payload_request):
return False

# [Modified in Electra]
if not self.notify_new_payload(execution_payload,
parent_beacon_block_root,
get_base_fee_per_blob_gas(state)):
return False

state.excess_blob_gas += execution_payload.blob_gas_used
dankrad marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this like should be a part of the process_execution_payload. The other thing is that there is no excess blob gas computation, I believe it should be computed as follows:

def compute_excess_blob_gas(excess_blob_gas: uint64, blob_gas_used: uint64) -> uint64:
    if blob_gas_used > TARGET_BLOB_GAS_PER_BLOCK:
        return excess_blob_gas + blob_gas_used - TARGET_BLOB_GAS_PER_BLOCK
    else:
        if excess_blob_gas < TARGET_BLOB_GAS_PER_BLOCK - blob_gas_used
            return uint64(0)
        else:
            return excess_blob_gas - (TARGET_BLOB_GAS_PER_BLOCK - blob_gas_used)


return True
```

### Epoch processing

#### Updated `process_epoch`
Expand Down
37 changes: 37 additions & 0 deletions specs/electra/fork-choice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Electra -- Fork Choice

## Table of contents
<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Containers](#containers)
- [Helpers](#helpers)
- [Extended `PayloadAttributes`](#extended-payloadattributes)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->

## Introduction

This is the modification of the fork choice accompanying the Electra upgrade.

## Containers

## Helpers

### Extended `PayloadAttributes`

`PayloadAttributes` is extended with the maximum number of blobs per block.

```python
@dataclass
class PayloadAttributes(object):
timestamp: uint64
prev_randao: Bytes32
suggested_fee_recipient: ExecutionAddress
withdrawals: Sequence[Withdrawal]
parent_beacon_block_root: Root
base_fee_per_blob_gas: uint64 # [New in Electra]
```
1 change: 1 addition & 0 deletions specs/electra/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def prepare_execution_payload(state: BeaconState,
suggested_fee_recipient=suggested_fee_recipient,
withdrawals=withdrawals,
parent_beacon_block_root=hash_tree_root(state.latest_block_header),
base_fee_per_blob_gas=state.base_fee_per_blob_gas, # [New in Electra]
)
return execution_engine.notify_forkchoice_updated(
head_block_hash=parent_hash,
Expand Down
Loading