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

Update EIP-4844: add data_gas_used to header #7062

Merged
merged 3 commits into from
Jun 1, 2023
Merged
Changes from all commits
Commits
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
37 changes: 21 additions & 16 deletions EIPS/eip-4844.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ The signature values `y_parity`, `r`, and `s` are calculated by constructing a s

### Header extension

The current header encoding is extended with a new 256-bit unsigned integer field `excess_data_gas`. This is the running total of excess data gas consumed on chain since this EIP was activated. If the total amount of data gas is below the
The current header encoding is extended with a new 64-bit unsigned integer field `data_gas_used` and a 256-bit unsigned integer field `excess_data_gas`. This is the running total of excess data gas consumed on chain since this EIP was activated. If the total amount of data gas is below the
target, `excess_data_gas` is capped at zero.

The resulting RLP encoding of the header is therefore:
Expand All @@ -146,21 +146,22 @@ rlp([
0x0000000000000000, # nonce
base_fee_per_gas,
withdrawals_root,
excess_data_gas
data_gas_used,
excess_data_gas,
])
```

The value of `excess_data_gas` can be calculated using the parent header and number of blobs in the block.
The value of `excess_data_gas` can be calculated using the parent header.

```python
def calc_excess_data_gas(parent: Header, consumed_data_gas: int) -> int:
if parent.excess_data_gas + consumed_data_gas < TARGET_DATA_GAS_PER_BLOCK:
def calc_excess_data_gas(parent: Header) -> int:
if parent.excess_data_gas + parent.data_gas_used < TARGET_DATA_GAS_PER_BLOCK:
lightclient marked this conversation as resolved.
Show resolved Hide resolved
return 0
else:
return parent.excess_data_gas + consumed_data_gas - TARGET_DATA_GAS_PER_BLOCK
return parent.excess_data_gas + parent.data_gas_used - TARGET_DATA_GAS_PER_BLOCK
```

For the first post-fork block, `parent.excess_data_gas` is evaluated as `0`.
For the first post-fork block, both `parent.data_gas_used` and `parent.excess_data_gas` are evaluated as `0`.

### Opcode to get versioned hashes

Expand Down Expand Up @@ -208,8 +209,8 @@ We introduce data gas as a new type of gas. It is independent of normal gas and
We use the `excess_data_gas` header field to store persistent data needed to compute the data gas price. For now, only blobs are priced in data gas.

```python
def calc_data_fee(tx: SignedBlobTransaction, parent: Header) -> int:
return get_total_data_gas(tx) * get_data_gasprice(parent)
def calc_data_fee(header: Header, tx: SignedBlobTransaction) -> int:
return get_total_data_gas(tx) * get_data_gasprice(header)

def get_total_data_gas(tx: SignedBlobTransaction) -> int:
return DATA_GAS_PER_BLOB * len(tx.blob_versioned_hashes)
Expand Down Expand Up @@ -249,9 +250,12 @@ On the execution layer, the block validity conditions are extended as follows:
```python
def validate_block(block: Block) -> None:
...

# check that the excess data gas was updated correctly
lightclient marked this conversation as resolved.
Show resolved Hide resolved
assert block.header.excess_data_gas == calc_excess_data_gas(block.parent.header)

block_data_gas = 0

data_gas_used = 0
lightclient marked this conversation as resolved.
Show resolved Hide resolved
for tx in block.transactions:
...

Expand All @@ -276,16 +280,17 @@ def validate_block(block: Block) -> None:
assert h[0] == BLOB_COMMITMENT_VERSION_KZG

# ensure that the user was willing to at least pay the current data gasprice
assert tx.max_fee_per_data_gas >= get_data_gasprice(parent(block).header)
assert tx.max_fee_per_data_gas >= get_data_gasprice(block.header)

# keep track of total data gas spent in the block
block_data_gas += get_total_data_gas(tx)
data_gas_used += get_total_data_gas(tx)

# ensure the total data gas spent is at most equal to the limit
assert block_data_gas <= MAX_DATA_GAS_PER_BLOCK
assert data_gas_used <= MAX_DATA_GAS_PER_BLOCK

# ensure data_gas_used matches header
assert block.header.data_gas_used == data_gas_used

lightclient marked this conversation as resolved.
Show resolved Hide resolved
# check that the excess data gas was updated correctly
assert block.header.excess_data_gas == calc_excess_data_gas(parent(block).header, block_data_gas)
```

### Networking
Expand Down