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: Remove system contract concept #5353

Merged
merged 7 commits into from
Sep 8, 2022
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
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.
Copy link
Member

Choose a reason for hiding this comment

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

Is this blobs here excess_blobs?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed in #5629, thanks for catching


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:
lightclient marked this conversation as resolved.
Show resolved Hide resolved

```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