Skip to content
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_NEXT --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 @@ -1025,15 +1027,32 @@ def process_transaction(
# coinbase. Burn them here so post-state roots match a client that
# implements MIP-11 fully.

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 @@ -1045,7 +1064,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