Skip to content
Draft
Show file tree
Hide file tree
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
4 changes: 4 additions & 0 deletions .github/configs/feature.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ monad:
# (triggered by tarball output) fails to proceed on no tests processed
# in 1st phase (exit code 5)
fill-params: --suppress-no-test-exit-code -m blockchain_test --from=MONAD_EIGHT --until=MONAD_NINE --chain-id=143 -k "not invalid_header"

monad_amsterdam:
evm-type: eels
fill-params: --suppress-no-test-exit-code -m blockchain_test --fork=MONAD_NEXT --chain-id=143 -k "not invalid_header" tests/amsterdam/eip7708_eth_transfer_logs tests/amsterdam/eip7843_slotnum tests/amsterdam/eip8024_dupn_swapn_exchange
226 changes: 144 additions & 82 deletions packages/testing/src/execution_testing/forks/forks/forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1666,8 +1666,111 @@ def c(w: int) -> int:
return fn


class MONAD_NEXT(MONAD_NINE, solc_name="cancun"): # noqa: N801
"""MONAD_NEXT fork."""
class BPO1(
Osaka,
bpo_fork=True,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 8346193,
"TARGET_BLOBS_PER_BLOCK": 10,
"MAX_BLOBS_PER_BLOCK": 15,
},
):
"""Mainnet BPO1 fork - Blob Parameter Only fork 1."""

pass


class BPO2(
BPO1,
bpo_fork=True,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 11684671,
"TARGET_BLOBS_PER_BLOCK": 14,
"MAX_BLOBS_PER_BLOCK": 21,
},
):
"""Mainnet BPO2 fork - Blob Parameter Only fork 2."""

pass


class BPO3(
BPO2,
bpo_fork=True,
deployed=False,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 20609697,
"TARGET_BLOBS_PER_BLOCK": 21,
"MAX_BLOBS_PER_BLOCK": 32,
},
):
"""
Pseudo BPO3 fork - Blob Parameter Only fork 3.
For testing purposes only.
"""

pass


class BPO4(
BPO3,
bpo_fork=True,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 13739630,
"TARGET_BLOBS_PER_BLOCK": 14,
"MAX_BLOBS_PER_BLOCK": 21,
},
):
"""
Pseudo BPO4 fork - Blob Parameter Only fork 4.
For testing purposes only. Testing a decrease in values from BPO3.
"""

pass


class BPO5(
BPO4,
bpo_fork=True,
):
"""
Pseudo BPO5 fork - Blob Parameter Only fork 5.
For testing purposes only. Required to parse Fusaka devnet genesis files.
"""

pass


class Amsterdam(
AmsterdamEIPs,
BPO2,
deployed=False,
):
"""Amsterdam fork."""

# TODO: We may need to adjust which BPO Amsterdam inherits from as the
# related Amsterdam specs change over time, and before Amsterdam is
# live on mainnet.

pass


class MONAD_NEXT(MONAD_NINE, Amsterdam, solc_name="cancun"): # noqa: N801
"""
MONAD_NEXT fork.

Amsterdam-based successor to MONAD_NINE. Only the EIP-7708, EIP-7843
and EIP-8024 changes are inherited from Amsterdam; every other
Amsterdam change is pinned back to the MONAD_NINE parent.
"""

@classmethod
def valid_opcodes(cls) -> List[Opcodes]:
"""
Inherit the Amsterdam opcode set: SLOTNUM (EIP-7843) and SWAPN,
DUPN, EXCHANGE (EIP-8024) on top of the MONAD_NINE opcodes.
"""
return Amsterdam.valid_opcodes()

@classmethod
def gas_costs(cls) -> GasCosts:
Expand Down Expand Up @@ -1753,91 +1856,50 @@ def _calculate_sstore_gas_mip8(

return gas_cost

@classmethod
def max_code_size(cls) -> int:
"""Return spec from explicit parent (skip EIP-7954)."""
return MONAD_NINE.max_code_size()

class BPO1(
Osaka,
bpo_fork=True,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 8346193,
"TARGET_BLOBS_PER_BLOCK": 10,
"MAX_BLOBS_PER_BLOCK": 15,
},
):
"""Mainnet BPO1 fork - Blob Parameter Only fork 1."""

pass


class BPO2(
BPO1,
bpo_fork=True,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 11684671,
"TARGET_BLOBS_PER_BLOCK": 14,
"MAX_BLOBS_PER_BLOCK": 21,
},
):
"""Mainnet BPO2 fork - Blob Parameter Only fork 2."""

pass


class BPO3(
BPO2,
bpo_fork=True,
deployed=False,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 20609697,
"TARGET_BLOBS_PER_BLOCK": 21,
"MAX_BLOBS_PER_BLOCK": 32,
},
):
"""
Pseudo BPO3 fork - Blob Parameter Only fork 3.
For testing purposes only.
"""

pass


class BPO4(
BPO3,
bpo_fork=True,
update_blob_constants={
"BLOB_BASE_FEE_UPDATE_FRACTION": 13739630,
"TARGET_BLOBS_PER_BLOCK": 14,
"MAX_BLOBS_PER_BLOCK": 21,
},
):
"""
Pseudo BPO4 fork - Blob Parameter Only fork 4.
For testing purposes only. Testing a decrease in values from BPO3.
"""

pass
@classmethod
def calldata_gas_calculator(cls) -> CalldataGasCalculator:
"""Return spec from explicit parent (skip EIP-7976)."""
return MONAD_NINE.calldata_gas_calculator()

@classmethod
def transaction_data_floor_cost_calculator(
cls,
) -> TransactionDataFloorCostCalculator:
"""Return spec from explicit parent (skip EIP-7981)."""
return MONAD_NINE.transaction_data_floor_cost_calculator()

class BPO5(
BPO4,
bpo_fork=True,
):
"""
Pseudo BPO5 fork - Blob Parameter Only fork 5.
For testing purposes only. Required to parse Fusaka devnet genesis files.
"""
@classmethod
def transaction_intrinsic_cost_calculator(
cls,
) -> TransactionIntrinsicCostCalculator:
"""Return spec from explicit parent (skip EIP-7981)."""
return MONAD_NINE.transaction_intrinsic_cost_calculator()

pass
@classmethod
def header_bal_hash_required(cls) -> bool:
"""Return spec from explicit parent (skip EIP-7928)."""
return MONAD_NINE.header_bal_hash_required()

@classmethod
def empty_block_bal_item_count(cls) -> int:
"""Return spec from explicit parent (skip EIP-7928)."""
return MONAD_NINE.empty_block_bal_item_count()

class Amsterdam(
AmsterdamEIPs,
BPO2,
deployed=False,
):
"""Amsterdam fork."""
@classmethod
def engine_execution_payload_block_access_list(cls) -> bool:
"""Return spec from explicit parent (skip EIP-7928)."""
return MONAD_NINE.engine_execution_payload_block_access_list()

# TODO: We may need to adjust which BPO Amsterdam inherits from as the
# related Amsterdam specs change over time, and before Amsterdam is
# live on mainnet.

pass
# MONAD_NEXT adopts EIP-7708, EIP-7843 and EIP-8024 from Amsterdam through the
# MRO rather than by inheriting their mixin classes: inheriting them would
# register MONAD_NEXT as a spurious `enabling_fork` (breaking
# `valid_at_transition_to`) and pull in EIP-7843's engine version bumps.
# Record the adopted EIP numbers on `_enabled_eips` directly so that
# `is_eip_enabled()` reports them without those side effects.
MONAD_NEXT._enabled_eips |= {7708, 7843, 8024}
8 changes: 8 additions & 0 deletions src/ethereum/forks/monad_next/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,14 @@ class Header:
[SHA2-256]: https://en.wikipedia.org/wiki/SHA-2
"""

slot_number: U64
"""
The slot number of this block as provided by the consensus layer.
Introduced in [EIP-7843].

[EIP-7843]: https://eips.ethereum.org/EIPS/eip-7843
"""


@final
@slotted_freezable
Expand Down
30 changes: 26 additions & 4 deletions src/ethereum/forks/monad_next/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
State,
apply_changes_to_state,
)
from ethereum.utils.byte import left_pad_zero_bytes

from . import vm
from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt
Expand Down Expand Up @@ -294,6 +295,7 @@ def state_transition(chain: BlockChain, block: Block) -> None:
prev_randao=block.header.prev_randao,
excess_blob_gas=block.header.excess_blob_gas,
parent_beacon_block_root=block.header.parent_beacon_block_root,
slot_number=block.header.slot_number,
)

block_output = apply_body(
Expand Down Expand Up @@ -1019,15 +1021,32 @@ def process_transaction(
# transfer miner fees
create_ether(tx_state, block_env.coinbase, U256(transaction_fee))

for address in tx_output.accounts_to_delete:
destroy_account(tx_state, address)
# EIP-7708: Emit burn logs for balances held by accounts marked for
# deletion AFTER miner fee transfer.
finalization_logs: List[Log] = []
for address in sorted(tx_output.accounts_to_delete):
balance = get_account(tx_state, address).balance
if balance > U256(0):
padded_address = left_pad_zero_bytes(address, 32)
finalization_logs.append(
Log(
address=vm.SYSTEM_ADDRESS,
topics=(
vm.BURN_TOPIC,
Hash32(padded_address),
),
data=balance.to_be_bytes32(),
)
)

all_logs = tx_output.logs + tuple(finalization_logs)

# block_output.block_gas_used += tx_gas_used_after_refund
block_output.block_gas_used += tx.gas
block_output.blob_gas_used += tx_blob_gas_used

receipt = make_receipt(
tx, tx_output.error, block_output.block_gas_used, tx_output.logs
tx, tx_output.error, block_output.block_gas_used, all_logs
)

receipt_key = rlp.encode(Uint(index))
Expand All @@ -1039,7 +1058,10 @@ def process_transaction(
receipt,
)

block_output.block_logs += tx_output.logs
block_output.block_logs += all_logs

for address in tx_output.accounts_to_delete:
destroy_account(tx_state, address)

incorporate_tx_into_block(tx_state)

Expand Down
Loading