mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-04 14:54:53 +00:00
Rebase Merge spec with London
This commit is contained in:
parent
bb16365eb1
commit
9a1a30c3d4
@ -59,6 +59,10 @@ This patch adds transaction execution to the beacon chain as part of the Merge f
|
|||||||
| `MAX_BYTES_PER_OPAQUE_TRANSACTION` | `uint64(2**20)` (= 1,048,576) |
|
| `MAX_BYTES_PER_OPAQUE_TRANSACTION` | `uint64(2**20)` (= 1,048,576) |
|
||||||
| `MAX_TRANSACTIONS_PER_PAYLOAD` | `uint64(2**14)` (= 16,384) |
|
| `MAX_TRANSACTIONS_PER_PAYLOAD` | `uint64(2**14)` (= 16,384) |
|
||||||
| `BYTES_PER_LOGS_BLOOM` | `uint64(2**8)` (= 256) |
|
| `BYTES_PER_LOGS_BLOOM` | `uint64(2**8)` (= 256) |
|
||||||
|
| `GAS_LIMIT_DIVISOR` | `uint64(2**10)` (= 1,024) |
|
||||||
|
| `MIN_GAS_LIMIT` | `uint64(5000)` (= 5,000) |
|
||||||
|
| `BASE_FEE_MAX_CHANGE_DENOMINATOR` | `uint64(2**3)` (= 8) |
|
||||||
|
| `ELASTICITY_MULTIPLIER` | `uint64(2**1)` (= 2) |
|
||||||
|
|
||||||
## Containers
|
## Containers
|
||||||
|
|
||||||
@ -141,6 +145,7 @@ class ExecutionPayload(Container):
|
|||||||
gas_limit: uint64
|
gas_limit: uint64
|
||||||
gas_used: uint64
|
gas_used: uint64
|
||||||
timestamp: uint64
|
timestamp: uint64
|
||||||
|
base_fee_per_gas: uint64 # base fee introduced in eip-1559
|
||||||
# Extra payload fields
|
# Extra payload fields
|
||||||
block_hash: Hash32 # Hash of execution block
|
block_hash: Hash32 # Hash of execution block
|
||||||
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
|
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
|
||||||
@ -161,6 +166,7 @@ class ExecutionPayloadHeader(Container):
|
|||||||
gas_limit: uint64
|
gas_limit: uint64
|
||||||
gas_used: uint64
|
gas_used: uint64
|
||||||
timestamp: uint64
|
timestamp: uint64
|
||||||
|
base_fee_per_gas: uint64
|
||||||
# Extra payload fields
|
# Extra payload fields
|
||||||
block_hash: Hash32 # Hash of execution block
|
block_hash: Hash32 # Hash of execution block
|
||||||
transactions_root: Root
|
transactions_root: Root
|
||||||
@ -239,6 +245,51 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
|
|||||||
|
|
||||||
### Execution payload processing
|
### Execution payload processing
|
||||||
|
|
||||||
|
#### `is_valid_gas_limit`
|
||||||
|
|
||||||
|
```python
|
||||||
|
def is_valid_gas_limit(payload: ExecutionPayload, parent: ExecutionPayloadHeader) -> bool:
|
||||||
|
parent_gas_limit = parent.gas_limit
|
||||||
|
|
||||||
|
# check if the payload used too much gas
|
||||||
|
if payload.gas_used > payload.gas_limit:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# check if the payload changed the gas limit too much
|
||||||
|
if payload.gas_limit >= parent_gas_limit + parent_gas_limit // GAS_LIMIT_DIVISOR:
|
||||||
|
return False
|
||||||
|
if payload.gas_limit <= parent_gas_limit - parent_gas_limit // GAS_LIMIT_DIVISOR:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# check if the gas limit is at least the minimum gas limit
|
||||||
|
if payload.gas_limit < MIN_GAS_LIMIT:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `compute_base_fee_per_gas`
|
||||||
|
|
||||||
|
```python
|
||||||
|
def compute_base_fee_per_gas(payload: ExecutionPayload, parent: ExecutionPayloadHeader) -> uint64:
|
||||||
|
parent_gas_target = parent.gas_limit // ELASTICITY_MULTIPLIER
|
||||||
|
parent_base_fee_per_gas = parent.base_fee_per_gas
|
||||||
|
parent_gas_used = payload.gas_used
|
||||||
|
|
||||||
|
if parent_gas_used == parent_gas_target:
|
||||||
|
return parent_base_fee_per_gas
|
||||||
|
elif parent_gas_used > parent_gas_target:
|
||||||
|
gas_used_delta = parent_gas_used - parent_gas_target
|
||||||
|
base_fee_per_gas_delta = \
|
||||||
|
max(parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
|
||||||
|
return parent_base_fee_per_gas + base_fee_per_gas_delta
|
||||||
|
else:
|
||||||
|
gas_used_delta = parent_gas_target - parent_gas_used
|
||||||
|
base_fee_per_gas_delta = \
|
||||||
|
parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR
|
||||||
|
return max(parent_base_fee_per_gas - base_fee_per_gas_delta, 0)
|
||||||
|
```
|
||||||
|
|
||||||
#### `process_execution_payload`
|
#### `process_execution_payload`
|
||||||
|
|
||||||
*Note:* This function depends on `process_randao` function call as it retrieves the most recent randao mix from the `state`. Implementations that are considering parallel processing of execution payload with respect to beacon chain state transition function should work around this dependency.
|
*Note:* This function depends on `process_randao` function call as it retrieves the most recent randao mix from the `state`. Implementations that are considering parallel processing of execution payload with respect to beacon chain state transition function should work around this dependency.
|
||||||
@ -250,6 +301,8 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
|
|||||||
assert payload.parent_hash == state.latest_execution_payload_header.block_hash
|
assert payload.parent_hash == state.latest_execution_payload_header.block_hash
|
||||||
assert payload.block_number == state.latest_execution_payload_header.block_number + uint64(1)
|
assert payload.block_number == state.latest_execution_payload_header.block_number + uint64(1)
|
||||||
assert payload.random == get_randao_mix(state, get_current_epoch(state))
|
assert payload.random == get_randao_mix(state, get_current_epoch(state))
|
||||||
|
assert payload.base_fee_per_gas == compute_base_fee_per_gas(payload, state.latest_execution_payload_header)
|
||||||
|
assert is_valid_gas_limit(payload, state.latest_execution_payload_header)
|
||||||
# Verify timestamp
|
# Verify timestamp
|
||||||
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
|
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
|
||||||
# Verify the execution payload is valid
|
# Verify the execution payload is valid
|
||||||
@ -266,6 +319,7 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
|
|||||||
gas_limit=payload.gas_limit,
|
gas_limit=payload.gas_limit,
|
||||||
gas_used=payload.gas_used,
|
gas_used=payload.gas_used,
|
||||||
timestamp=payload.timestamp,
|
timestamp=payload.timestamp,
|
||||||
|
base_fee_per_gas=payload.base_fee_per_gas,
|
||||||
block_hash=payload.block_hash,
|
block_hash=payload.block_hash,
|
||||||
transactions_root=hash_tree_root(payload.transactions),
|
transactions_root=hash_tree_root(payload.transactions),
|
||||||
)
|
)
|
||||||
@ -321,6 +375,7 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
|
|||||||
state.latest_execution_payload_header.block_hash = eth1_block_hash
|
state.latest_execution_payload_header.block_hash = eth1_block_hash
|
||||||
state.latest_execution_payload_header.timestamp = eth1_timestamp
|
state.latest_execution_payload_header.timestamp = eth1_timestamp
|
||||||
state.latest_execution_payload_header.random = eth1_block_hash
|
state.latest_execution_payload_header.random = eth1_block_hash
|
||||||
|
state.latest_execution_payload_header.gas_limit = MIN_GAS_LIMIT
|
||||||
|
|
||||||
return state
|
return state
|
||||||
```
|
```
|
||||||
|
@ -17,12 +17,14 @@ def build_empty_execution_payload(spec, state, randao_mix=None):
|
|||||||
logs_bloom=spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), # TODO: zeroed logs bloom for empty logs ok?
|
logs_bloom=spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), # TODO: zeroed logs bloom for empty logs ok?
|
||||||
block_number=latest.block_number + 1,
|
block_number=latest.block_number + 1,
|
||||||
random=randao_mix,
|
random=randao_mix,
|
||||||
gas_limit=latest.gas_limit, # retain same limit
|
gas_limit=max(latest.gas_limit, spec.MIN_GAS_LIMIT),
|
||||||
gas_used=0, # empty block, 0 gas
|
gas_used=0, # empty block, 0 gas
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
|
base_fee_per_gas=spec.uint64(0),
|
||||||
block_hash=spec.Hash32(),
|
block_hash=spec.Hash32(),
|
||||||
transactions=empty_txs,
|
transactions=empty_txs,
|
||||||
)
|
)
|
||||||
|
payload.base_fee_per_gas = spec.compute_base_fee_per_gas(latest, payload)
|
||||||
# TODO: real RLP + block hash logic would be nice, requires RLP and keccak256 dependency however.
|
# TODO: real RLP + block hash logic would be nice, requires RLP and keccak256 dependency however.
|
||||||
payload.block_hash = spec.Hash32(spec.hash(payload.hash_tree_root() + b"FAKE RLP HASH"))
|
payload.block_hash = spec.Hash32(spec.hash(payload.hash_tree_root() + b"FAKE RLP HASH"))
|
||||||
|
|
||||||
@ -41,6 +43,7 @@ def get_execution_payload_header(spec, execution_payload):
|
|||||||
gas_limit=execution_payload.gas_limit,
|
gas_limit=execution_payload.gas_limit,
|
||||||
gas_used=execution_payload.gas_used,
|
gas_used=execution_payload.gas_used,
|
||||||
timestamp=execution_payload.timestamp,
|
timestamp=execution_payload.timestamp,
|
||||||
|
base_fee_per_gas=execution_payload.base_fee_per_gas,
|
||||||
block_hash=execution_payload.block_hash,
|
block_hash=execution_payload.block_hash,
|
||||||
transactions_root=spec.hash_tree_root(execution_payload.transactions)
|
transactions_root=spec.hash_tree_root(execution_payload.transactions)
|
||||||
)
|
)
|
||||||
|
@ -78,5 +78,6 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
|
|||||||
# Initialize the execution payload header (with block number and genesis time set to 0)
|
# Initialize the execution payload header (with block number and genesis time set to 0)
|
||||||
state.latest_execution_payload_header.block_hash = eth1_block_hash
|
state.latest_execution_payload_header.block_hash = eth1_block_hash
|
||||||
state.latest_execution_payload_header.random = eth1_block_hash
|
state.latest_execution_payload_header.random = eth1_block_hash
|
||||||
|
state.latest_execution_payload_header.gas_limit = spec.MIN_GAS_LIMIT
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user