Skip to content

Commit

Permalink
Update EIP-4844: Remove system contract concept (#5353)
Browse files Browse the repository at this point in the history
* remove system contract concept

* store excess blob count in header instead of adjusted-total

Co-authored-by: vbuterin <v@buterin.com>
Co-authored-by: lightclient <lightclient@protonmail.com>

* revert previous name change

* update again

* should account for blobs, not blob txs

* fix

* apply review feedback

Co-authored-by: Ansgar Dietrichs <adietrichs@gmail.com>
Co-authored-by: lightclient <lightclient@protonmail.com>

Co-authored-by: vbuterin <v@buterin.com>
Co-authored-by: Ansgar Dietrichs <adietrichs@gmail.com>
  • Loading branch information
3 people authored Sep 8, 2022
1 parent c26d36b commit 2d98342
Showing 1 changed file with 49 additions and 44 deletions.
93 changes: 49 additions & 44 deletions EIPS/eip-4844.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ Compared to full data sharding, this EIP has a reduced cap on the number of thes

| Constant | Value |
| - | - |
| `SYSTEM_STATE_ADDRESS` | `0x000.....0100`|
| `TOTAL_BLOB_TXS_STORAGE_SLOT` | `0` |
| `BLOB_TX_TYPE` | `Bytes1(0x05)` |
| `FIELD_ELEMENTS_PER_BLOB` | `4096` |
| `BLS_MODULUS` | `52435875175126190479447740508185965837690552500527637822603658699938581184513` |
Expand Down Expand Up @@ -234,6 +232,46 @@ def get_origin(tx: SignedBlobTransaction) -> Address:
return ecrecover(tx_hash(tx), int(sig.y_parity)+27, sig.r, sig.s)
```

### Header extension

The current header encoding is extended with a new 256-bit unsigned integer field `excess_blobs`. This is the running
total of excess blobs included on chain since this EIP was activated. If the total number of blobs is below the
average, `excess_blobs` is capped at zero.

The resulting RLP encoding of the header is therefore:

```
rlp([
parent_hash,
ommers_hash,
coinbase,
state_root,
tx_root,
receipt_root,
bloom,
difficulty,
number,
gas_limit,
gas_used,
time,
extra,
mix_digest,
nonce,
base_fee,
excess_blobs
])
```

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

```python
def calc_excess_blobs(parent: Header, new_blobs: int) -> int:
if parent.excess_blobs + new_blobs < TARGET_BLOBS_PER_BLOCK:
return 0
else:
return parent.excess_blobs + new_blobs - TARGET_BLOBS_PER_BLOCK
```

### Beacon chain validation

On the consensus-layer the blobs are now referenced, but not fully encoded, in the beacon block body.
Expand Down Expand Up @@ -290,8 +328,8 @@ For early draft implementations, we simply change `get_blob_gas(pre_state)` to a
### Gas price update rule (Full version)

We propose a simple independent EIP-1559-style targeting rule to compute the gas cost of the transaction.
We use the `TOTAL_BLOB_TXS_STORAGE_SLOT` storage slot of the `SYSTEM_STATE_ADDRESS` address
to store persistent data needed to compute the cost.
We use the `blobs` header field to store persistent data needed to compute the cost.

Note that unlike existing transaction types, the gas cost is dependent on the pre-state of the block.

```python
Expand All @@ -307,42 +345,10 @@ def get_intrinsic_gas(tx: SignedBlobTransaction, pre_state: ExecState) -> int:
intrinsic_gas += len(tx.message.blob_versioned_hashes) * get_blob_gas(pre_state)
return intrinsic_gas

def get_blob_gas(pre_state: ExecState) -> int:
blocks_since_start = get_current_block(pre_state) - FORK_BLKNUM
targeted_total = blocks_since_start * TARGET_BLOB_TXS_PER_BLOCK
actual_total = read_storage(
pre_state,
SYSTEM_STATE_ADDRESS,
TOTAL_BLOB_TXS_STORAGE_SLOT
)
if actual_total < targeted_total:
return 0
else:
return fake_exponential(
actual_total - targeted_total,
GASPRICE_UPDATE_FRACTION_PER_BLOB
)
```

We update at the end of a block, as follows:

```python
def update_blob_gas(state: ExecState, blob_txs_in_block: int):
current_total = read_storage(
state,
SYSTEM_STATE_ADDRESS,
TOTAL_BLOB_TXS_STORAGE_SLOT
)
# Don't let the new total fall behind the targeted total to avoid
# accumulating a long period of very low fees
blocks_since_start = get_current_block(pre_state) - FORK_BLKNUM
targeted_total = blocks_since_start * TARGET_BLOB_TXS_PER_BLOCK
new_total = max(current_total + blob_txs_in_block, targeted_total)
write_storage(
state,
SYSTEM_STATE_ADDRESS,
TOTAL_BLOB_TXS_STORAGE_SLOT,
new_total
def get_blob_gas(header: Header) -> int:
return fake_exponential(
header.excess_blobs,
GASPRICE_UPDATE_FRACTION_PER_BLOB
)
```

Expand Down Expand Up @@ -465,7 +471,6 @@ This EIP also sets the stage for longer-term protocol cleanups:
and paves the precedent that all new transaction types should be SSZ
* It defines `TransactionNetworkPayload` to separate network and block encodings of a transaction type
* Its (cleaner) gas price update rule could be applied to the primary basefee.
It also starts the trend toward using the state to store system state instead of having "implied state" such as historical blocks and hashes.

### How rollups would function

Expand Down Expand Up @@ -494,12 +499,12 @@ sequencers would simply have to switch over to using a new transaction type at t
### Blob gasprice update rule

The blob gasprice update rule is intended to approximate the formula `blob_gas = 2**(excess_blobs / GASPRICE_UPDATE_FRACTION_PER_BLOB)`,
where `excess_blobs` is the total "extra" number of blobs that the chain has accepted relative to the "targeted" number (`TARGET_BLOB_TXS_PER_BLOCK` per block).
where `excess_blobs` is the total "extra" number of blobs that the chain has accepted relative to the "targeted" number (`TARGET_BLOBS_PER_BLOCK` per block).
Like EIP-1559, it's a self-correcting formula: as the excess goes higher, the `blob_gas` increases exponentially, reducing usage and eventually forcing the excess back down.

The block-by-block behavior is roughly as follows.
If in block `N`, `blob_gas = G1`, and block `N` has `X` blobs, then in block `N+1`, `excess_blobs` increases by `X - TARGET_BLOB_TXS_PER_BLOCK`,
and so the `blob_gas` of block `N+1` increases by a factor of `2**((X - TARGET_BLOB_TXS_PER_BLOCK) / GASPRICE_UPDATE_FRACTION_PER_BLOB)`.
If in block `N`, `blob_gas = G1`, and block `N` has `X` blobs, then in block `N+1`, `excess_blobs` increases by `X - TARGET_BLOBS_PER_BLOCK`,
and so the `blob_gas` of block `N+1` increases by a factor of `2**((X - TARGET_BLOBS_PER_BLOCK) / GASPRICE_UPDATE_FRACTION_PER_BLOB)`.
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.

## Backwards Compatibility
Expand Down

0 comments on commit 2d98342

Please sign in to comment.