Skip to content
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
26 changes: 13 additions & 13 deletions EIPS/eip-4844.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Compared to full data sharding, this EIP has a reduced cap on the number of thes
| `POINT_EVALUATION_PRECOMPILE_GAS` | `50000` |
| `MAX_BLOB_GAS_PER_BLOCK` | `786432` |
| `TARGET_BLOB_GAS_PER_BLOCK` | `393216` |
| `MIN_BLOB_BASE_FEE` | `1` |
| `MIN_BASE_FEE_PER_BLOB_GAS` | `1` |
| `BLOB_BASE_FEE_UPDATE_FRACTION` | `3338477` |
| `GAS_PER_BLOB` | `2**17` |
| `HASH_OPCODE_BYTE` | `Bytes1(0x49)` |
Expand Down Expand Up @@ -168,23 +168,23 @@ We introduce blob gas as a new type of gas. It is independent of normal gas and
We use the `excess_blob_gas` header field to store persistent data needed to compute the blob gas base fee. For now, only blobs are priced in blob gas.

```python
def calc_data_fee(header: Header, tx: Transaction) -> int:
return get_total_blob_gas(tx) * get_blob_base_fee(header)
def calc_blob_fee(header: Header, tx: Transaction) -> int:
return get_total_blob_gas(tx) * get_base_fee_per_blob_gas(header)

def get_total_blob_gas(tx: Transaction) -> int:
return GAS_PER_BLOB * len(tx.blob_versioned_hashes)

def get_blob_base_fee(header: Header) -> int:
def get_base_fee_per_blob_gas(header: Header) -> int:
return fake_exponential(
MIN_BLOB_BASE_FEE,
MIN_BASE_FEE_PER_BLOB_GAS,
header.excess_blob_gas,
BLOB_BASE_FEE_UPDATE_FRACTION
)
```

The block validity conditions are modified to include blob gas checks (see the [Execution layer validation](#execution-layer-validation) section below).

The actual `data_fee` as calculated via `calc_data_fee` is deducted from the sender balance before transaction execution and burned, and is not refunded in case of transaction failure.
The actual `blob_fee` as calculated via `calc_blob_fee` is deducted from the sender balance before transaction execution and burned, and is not refunded in case of transaction failure.

### Opcode to get versioned hashes

Expand Down Expand Up @@ -276,7 +276,7 @@ def validate_block(block: Block) -> None:
assert h[0] == VERSIONED_HASH_VERSION_KZG

# ensure that the user was willing to at least pay the current blob base fee
assert tx.max_fee_per_blob_gas >= get_blob_base_fee(block.header)
assert tx.max_fee_per_blob_gas >= get_base_fee_per_blob_gas(block.header)

# keep track of total blob gas spent in the block
blob_gas_used += get_total_blob_gas(tx)
Expand Down Expand Up @@ -383,18 +383,18 @@ However, the point evaluation happens inside a finite field, and it is only well

In the interest of not adding another precompile, we return the modulus and the polynomial degree directly from the point evaluation precompile. It can then be used by the caller. It is also "free" in that the caller can just ignore this part of the return value without incurring an extra cost -- systems that remain upgradable for the foreseeable future will likely use this route for now.

### Blob base fee update rule
### Base fee per blob gas update rule

The blob base fee update rule is intended to approximate the formula `blob_base_fee = MIN_BLOB_BASE_FEE * e**(excess_blob_gas / BLOB_BASE_FEE_UPDATE_FRACTION)`,
The base fee per blob gas update rule is intended to approximate the formula `base_fee_per_blob_gas = MIN_BASE_FEE_PER_BLOB_GAS * e**(excess_blob_gas / BLOB_BASE_FEE_UPDATE_FRACTION)`,
where `excess_blob_gas` is the total "extra" amount of blob gas that the chain has consumed relative to the "targeted" number (`TARGET_BLOB_GAS_PER_BLOCK` per block).
Like EIP-1559, it's a self-correcting formula: as the excess goes higher, the `blob_base_fee` increases exponentially, reducing usage and eventually forcing the excess back down.
Like EIP-1559, it's a self-correcting formula: as the excess goes higher, the `base_fee_per_blob_gas` increases exponentially, reducing usage and eventually forcing the excess back down.

The block-by-block behavior is roughly as follows.
If block `N` consumes `X` blob gas, then in block `N+1` `excess_blob_gas` increases by `X - TARGET_BLOB_GAS_PER_BLOCK`,
and so the `blob_base_fee` of block `N+1` increases by a factor of `e**((X - TARGET_BLOB_GAS_PER_BLOCK) / BLOB_BASE_FEE_UPDATE_FRACTION)`.
and so the `base_fee_per_blob_gas` of block `N+1` increases by a factor of `e**((X - TARGET_BLOB_GAS_PER_BLOCK) / BLOB_BASE_FEE_UPDATE_FRACTION)`.
Hence, it has a similar effect to the existing EIP-1559, but is more "stable" in the sense that it responds in the same way to the same total usage regardless of how it's distributed.

The parameter `BLOB_BASE_FEE_UPDATE_FRACTION` controls the maximum rate of change of the blob base fee. It is chosen to target a maximum change rate of `e**(TARGET_BLOB_GAS_PER_BLOCK / BLOB_BASE_FEE_UPDATE_FRACTION) ≈ 1.125` per block.
The parameter `BLOB_BASE_FEE_UPDATE_FRACTION` controls the maximum rate of change of the base fee per blob gas. It is chosen to target a maximum change rate of `e**(TARGET_BLOB_GAS_PER_BLOCK / BLOB_BASE_FEE_UPDATE_FRACTION) ≈ 1.125` per block.

### Throughput

Expand All @@ -417,7 +417,7 @@ By only broadcasting announcements for blob transactions, receiving nodes will h
allowing them to throttle throughput to an acceptable level.
[EIP-5793](./eip-5793.md) will give further fine-grained control to nodes by extending the `NewPooledTransactionHashes` announcement messages to include the transaction type and size.

In addition, we recommend including a 1.1x blob base fee bump requirement to the mempool transaction replacement rules.
In addition, we recommend including a 1.1x base fee per blob gas bump requirement to the mempool transaction replacement rules.

## Test Cases

Expand Down