Skip to content

Merge from upstream - #63

Merged
pdobacz merged 45 commits into
forks/monad_ninefrom
from-upstream
Oct 14, 2026
Merged

pdobacz merged 45 commits into
forks/monad_ninefrom
from-upstream

Conversation

@pdobacz

@pdobacz pdobacz commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

IMPORTANT: Merge with merge commit !

Merges upstream/forks/bogota

Release set: 53866 -> 54027 fixtures (+152 precompile boundary, +6 invalid-first-tx, +3 reinvoked selfdestruct nonce; 24 ids renamed).

RetriggerConfidence Score: 4/5

Fix the two custom-coinbase tests before merging so remote runs do not fail against correct clients.

Fix All in Claude CodeFindings

  1. P1 Remote coinbase tests fail ▶
  2. P2 Merged checks disappear ▶
  3. P2 Check metadata misses relative checks ▶
Fix with agent prompt
### Issue 1
tests/amsterdam/eip8246_selfdestruct_no_burn/test_selfdestruct_no_burn.py:292
Both new `test_created_coinbase_*` tests require the block to pay fees to `created`, but they also run under `execute remote`. `StateTest.execute()` drops the supplied `Environment`, while `Tip.check_recipient()` checks the real block's fee recipient. These cases therefore fail against a correct remote client. Add an execute-only skip to both tests, as the other custom-coinbase tests do.

### Issue 2
packages/testing/src/execution_testing/test_types/account_types.py:425-426
`Account.merge()` drops the new `balance_change` and `nonce_change` expectations. Both fields have `exclude=True`, so `model_dump(exclude_unset=True)` leaves them out even when explicitly supplied. Combining post expectations with this helper silently removes those checks. Copy explicitly set fields directly instead of using the fixture serialization path, and add merge tests for relative fields.

### Issue 3
packages/testing/src/execution_testing/specs/state.py:424-427
The new relative checks are missing from `--post-verifications` output. `verify_post_alloc()` checks `balance_change` and `nonce_change`, but `PostVerifications.from_alloc(self.post)` still records only explicitly set `balance` and `nonce`. The migrated fee tests therefore report no balance check even though one ran. Record the resolved expected values when building `PostVerifications`, including the corresponding blockchain paths.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Merges upstream Bogota support and test-framework updates.

  • Bogota executes blocks with its own rules and checks their access-list hash.
  • Tests can describe account changes relative to their starting state.
  • The test tools support earlier invalid transactions and cleaner test setup.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A["Relative post expectations"] --> B["Pre-state"]
  A --> C["Fee terms"]
  C --> D["Locally recorded block prices"]
  C --> E["Remote receipts and blocks"]
  B --> F["Resolve expected balance and nonce"]
  D --> F
  E --> F
  F --> G["Compare with post-state"]
Loading

Reviews (1) · Last reviewed commit: "charge the Monad gas limit in the EIP-15..." · Reviewed by Greptile

shubham5080 and others added 30 commits October 5, 2026 15:03
…um#3654)

* feat(tests): cover BAL same-index nonce keep and code replace

Add a post-execution two-call fixture that CREATEs then value-CALLs at
one block access index, hitting the previously untested keep/replace
branches in add_nonce_change and add_code_change.

Co-authored-by: Cursor <[email protected]>

* style(tests): format same-index BAL coverage test

Co-authored-by: Cursor <[email protected]>

* refactor(tests): reach the same-index BAL branches with one call per predeploy

* chore(tests): fix the eip7928 missed_lines entry and its re-verify command

* chore(skills): update checklist skill wording for better results

---------

Co-authored-by: Cursor <[email protected]>
Co-authored-by: fselmo <[email protected]>
…ct (ethereum#3674)

`consume direct --bin nethtest` passed every block test without running
it. Since NethermindEth/nethermind#10211, nethtest matches `--filter`
against the fixture key after `.py::`, so the full key EELS passed
matched nothing; and the result was read from the exit code alone,
which nethtest leaves at 0 when a test fails. Filter on the part after
`.py::`, and read the verdict from the JSON array on stdout, failing
when it is empty.

Fixes ethereum#3609.
…reum#3672)

A test directory holding a pytest function that requests no spec fixture
crashed `fill` with `INTERNALERROR> ValueError: No spec type format
found in the test item.`: the filler's `pytest_collection_modifyitems`
reached the item before the existing check in `pytest_runtest_call`
could run. Move that check to a `tryfirst` `pytest_generate_tests`, so
the module fails collection with a message naming the test, in a single
process and under xdist alike.

Fixes ethereum#3608.
…sponsored authorizations (ethereum#3671)

A client that undoes applied authorizations one by one, rather than
restoring a snapshot, can get the undo wrong when the halt follows an
authority authorized twice or a self-sponsored authorization, and still
pass every existing rollback test, which only use distinct third-party
authorities.

Add test_repeated_authority_rolled_back and
test_self_sponsored_authorization_rolled_back, each crossed with a
starved recipient NEW_ACCOUNT or delegation-access charge and a
succeeds control. Share the repeated-authority setup via
build_repeated_authority and let authorization_transaction_cost take a
recipient type.
…m#3678)

* test: enhance 7708, 8024 coverage

* feat: cover NEW_ACCOUNT charges for an absent coinbase

* fix(tests): Fixes and new test

---------

Co-authored-by: marioevz <[email protected]>
…wal (EIP-7928) (ethereum#3681)

* tests(eip7928): cover SYSTEM_ADDRESS accessed via delegation and withdrawal

* refactor(tests): tidy the SYSTEM_ADDRESS access tests

Import SYSTEM_ADDRESS like the sibling modules, drop the inline conditional in the withdrawal post-state, pin the delegation target's absence from post-state, shorten the docstrings, and add both tests to test_cases.md.

---------

Co-authored-by: fselmo <[email protected]>
)

* feat(test-specs): add the invalid_tx_not_last marker

* feat(tests): cover order-dependent transaction validity in a block

* feat(tests): cover BAL cross-tx hazards of parallel execution

* feat(tests): cover a 7702 authorization staled by a prior tx

* feat(tests): widen BAL cross-tx hazard coverage

Extend the read-before-write test to five transactions with a reverted last write, add a balance read before a later transfer or withdrawal, a cold-access check across two transactions, a 7702 delegation arm on the code-reads test, and receipt pins on the coinbase burners.

* feat(tests): cover a 7702 authorization made valid by a prior tx

The positive twin of the stale-nonce arm: a plain transaction from the authority bumps its nonce to the one the authorization signed, and the delegation must be applied.

* fix(tests): put the invalid first tx's sender in the block access list

The trailing transaction now sends value to the unfunded sender instead of to a bystander. That lists the sender in the block access list, so a client that reads state through the list reaches the funds check instead of failing on the missing account, and it makes the case a stronger trap: a client that applies the later credit before checking the first transaction accepts the block. Every fork still fills; the Amsterdam engine payload now carries the sender.

* feat(tests): reject a BAL missing an account touched by any read path

Widen the missing-account negative from two scenarios to eight: a zero-value CALL and a STATICCALL to an EOA, a precompile, the code source behind a delegated EOA, the authority of a failed authorization, and a read inside a frame that reverts. Each is a different client path to the same empty entry, so a client that builds its list from one path and not another fails the one it skips.

* docs(test-markers): put a rejected transaction's sender in the BAL

The transition tool skips a rejected transaction, so its sender only enters the block access list through another transaction. A client that loads accounts from the list then rejects the block for the missing account rather than for the reason under test, as reth did on the invalid-first fixture. Tell invalid_tx_not_last users to have a valid transaction send value to that sender when the rejection depends on its account.

* docs(tests): point the missing-account negative at its positive tests

One sentence so the next reader knows the failed-authorization presence is already pinned by the invalid-nonce test and this arm only covers the rejection.

* feat(tests): cover a rejected block leaving nonce and balance untouched

The next block spends the same nonce and the exact balance the rejected transaction claimed to need, so a client that consumed either on rejection fails it. One arm trails a valid transaction from a second sender behind the rejected one and replays it at the same nonce, pinning that trailing transactions leave no trace either. The fork-transition tests retry a transaction across blocks but their validity flips with the rules; none pinned this.

* chore: clean up AI verbosity

* refactor(tests): fold the nonce-order case into the invalid-first test

Both are a block whose first transaction is invalid and would have been valid had the one after it run first, so they share one test with a cause axis: an unfunded sender funded later, or a nonce 1 arriving before its nonce 0. The three-transaction gap-then-fill arm is dropped; it was the same case with an extra transaction in front.

* refactor(tests): replay the trailing tx after an invalid-first block

The next block replays the valid transaction that trailed the rejected one, at the same nonce, so the invalid-first test also pins that a trailing transaction in a rejected block leaves no trace. That was the only part of the rejected-block test worth keeping, so it is removed; its other arm, a rejected block deducting nothing, is table stakes that fails elsewhere first.

* refactor(tests): drop the funds-spent test as a duplicate

Cancun's test_insufficient_balance_blob_tx_combinations already sends several transactions from one sender funded at their combined cost minus one wei and rejects the last, with an exact-balance twin. The frontier version only added legacy transaction types, over the same upfront-balance check.

* refactor(tests): merge the 7702 nonce authorization tests

One test, three cases: an authorization nonce wrong in the pre-state, one made stale by the authority's own earlier transaction, and one made valid by it. The last two are a boundary pair around the nonce after the prior transaction, and the case ids say which is which, so the invalid and valid tests no longer need separate names.

* test(tests): tie the invalid-first test to BAL parallel execution

Say in the docstring that the test guards clients executing a block's transactions in parallel, pin the sender's block access list entry in both blocks from Amsterdam on (index 2 in the rejected block, index 1 in the replay), and add its row to the EIP-7928 test cases table.

* suggestions (#36)

---------

Co-authored-by: Mario Vega <[email protected]>
…reum#3702) (ethereum#3714)

`execute remote --collect-only` exited with "Chain ID must be provided"
unless a chain ID was passed, even though listing tests doesn't need
one. The RPC endpoint check in `remote.py` already skips help and
collect-only mode; do the same for the missing chain ID check.

Also drop the placeholder RPC flags from `just execute-collect`. Only
the chain ID was still required, and with this fix none are needed.

Fixes ethereum#1532.

(cherry picked from commit 571b355)

Co-authored-by: Call me Eddy <[email protected]>
…um#3698) (ethereum#3715)

* fix(evm-tools): build the BAL of a block that fails mid-way

When a block failed on a system call or a deposit log, t8n left its access list empty, so the header committed to a wrong list as well as to the failure under test. It now builds the list from what ran before the failure, which changes the 43 Amsterdam fixtures whose blocks fail this way.

* feat(test-specs): fail fill when a tx-rejected block is also invalid

Fill skipped the block exception whenever a transaction was rejected, so a block the transition tool also rejected (test_tx_gas_limit at a 21000 gas limit, over the EIP-7928 item cap) filled with two defects and one name. Fill now refuses such a block.

(cherry picked from commit 37f6de9)

Co-authored-by: felipe <[email protected]>
…ontract (ethereum#3705)

* feat(tests): cover CREATE nonce after re-invoking a self-destructed contract (EIP-8246)

* fix(tests): annotate call_a as returning Bytecode

* refactor(tests): move re-invoked selfdestruct CREATE nonce test into the EIP-6780 suite

---------

Co-authored-by: LouisTsai <[email protected]>
(cherry picked from commit 5792f4f)
)

Replace the two loose over-cap rejections with an exact pair: intrinsic execution gas equal to the cap is accepted and one zero calldata byte more is rejected, with the calldata floor below the cap.

(cherry picked from commit 57842a8)
Each call to the victim sends a different value that its child keeps, so the test now fails if the reverted frame's CREATE is not undone; before, a child at nonce 2 could have come from either call.

(cherry picked from commit 5131346)
… data floor (ethereum#3711)

* fix(test-benchmark): keep BLS12 MSM split transactions above the data floor

* refactor(test-benchmark): inline the BLS12 MSM helper and meter its EXTCODECOPY

* refactor(test-benchmark): fold the BLS12 G1/G2 MSM benchmarks into one test

---------

Co-authored-by: LouisTsai <[email protected]>
(cherry picked from commit 1764b08)
…reum#3606)

* fix(tests): fold CALL execution_cost + stale TODO cleanups

Co-authored-by: Cursor <[email protected]>

* refactor(tests): support pre-Berlin CALL gas and enhance revert-in-init

Co-authored-by: Cursor <[email protected]>

* fix(tests): use execution_cost and drop redundant account_new

Louis review: account_new is already False by default on all call
opcodes, and CodeGasMeasure expectations should use execution_cost.

Co-authored-by: Cursor <[email protected]>

* refactor(tests): tidy revert-in-init locals and zero-amount post type

---------

Co-authored-by: Cursor <[email protected]>
Co-authored-by: LouisTsai <[email protected]>
(cherry picked from commit 252aa9b)
* chore(tooling): keep imports that fit on one line in `src`

Add `src/ruff.toml`, extending the root configuration, with isort's
`split-on-trailing-comma` disabled. Ruff then joins an import that fits
on one line even when it has a trailing comma, so leftover commas can
no longer create formatting-only differences between forks.

* refactor(spec-specs): join imports that fit on one line

Apply `ruff check --select I --fix src` with the new isort setting.
Every change joins a parenthesized import onto one line; ASTs are
unchanged. This removes the import layout differences between
consecutive forks (for example Paris to Shanghai, Shanghai to Cancun
and BPO1 to BPO2).

(cherry picked from commit 1689800)
Apply the one-line import rule from ethereum#3720 to the Bogota module, which was copied from Amsterdam before that change landed.
… BPO forks (ethereum#3701)

BPO1-BPO5 are meant to differ from Osaka only in their blob schedule
and fork metadata, but several docstrings and comments had drifted
apart:

- Restore the SSTORE refund comments in Osaka, which were dropped in
  ethereum#2396 and are still present in every fork from Istanbul to BPO5.
- Port the `gas_limit` docstring update from ethereum#2300 to BPO1-BPO5,
  which still claimed a maximum of 30 million gas.
- Add the missing [EIP-7623] link definition to the BPO1-BPO5
  `calldata_floor` docstring, as in Prague and Osaka.
ethereum#3732)

* refactor(spec-tools): remove the formatting hygiene exception list

Drop `EXCEPTIONS` and its handling from the formatting hygiene lint, so
that it reports every formatting-only difference between consecutive
forks. This makes `just lint-spec` fail until those differences are
fixed.

* refactor(spec-specs): wrap the `check_gas_limit` docstring consistently

ethereum#2396 shortened the gas limit constant names in this docstring and
re-wrapped the paragraph in only half of the forks. Use the re-wrapped
version, which fills each line, in every fork.

* refactor(spec-specs): put one `create` gas argument per line

Split the `charge_gas` call in `create` one argument per line in
Shanghai, Cancun, Prague, BPO2 and BPO3, as in Osaka, BPO1, BPO4 and
BPO5. These were the only multi-line `charge_gas` calls with their
arguments on a single line.

* refactor(spec-specs): join Osaka's `get_account` arguments

ethereum#2396 split the `get_account` calls in Osaka's `callcode` and
`selfdestruct` one argument per line. Put the two arguments back on one
line, as in every other fork and every other multi-line `get_account`
call.

* refactor(spec-specs): put one `generic_create` argument per line

Split the `generic_create` calls in `create` and `create2` one argument
per line from Constantinople to Paris, as from Shanghai onwards and in
most other multi-line calls.

* refactor(spec-specs): put one `delegatecall` gas argument per line

Split the `calculate_message_call_gas` call in `delegatecall` one
argument per line from Berlin onwards, matching `staticcall`, which
passes the same arguments, and the Arrow Glacier and Osaka versions.

* refactor(spec-specs): remove stray blank lines in Osaka and London

Remove a blank line in Osaka's `access_delegation` and one before the
`else` in London's `process_message`. Neither fork's neighbours have
them.

* refactor(spec-specs): drop the blank line in the CREATE2 address helper

Remove the blank line before the `return` in
`compute_create2_contract_address` from Istanbul onwards, matching the
other address helpers in the module and Constantinople's version.

* refactor(spec-specs): separate the final return in `validate_transaction`

Add a blank line before `return intrinsic_gas` from London to Paris,
as from Shanghai onwards, so the fee checks and the return don't run
together.

* refactor(spec-specs): keep the nonce and balance checks together

Remove the blank line between the nonce checks and the balance check
in `check_transaction` from Prague to BPO5, as in every earlier fork.

* refactor(spec-specs): match BPO5's blank lines in Amsterdam and Bogota

Move the blank line after `set_code` in `set_delegation`, restore the
blank line before the `create` gas charge, and drop the blank line
after the memory expansion in the call opcodes, as in BPO5.
spencer-tb and others added 15 commits October 7, 2026 11:23
…thereum#3721)

* fix(test-forks,tests): fix latent base fee and blob transition bugs

* fix: use ceiling_division

* fix: tests

---------

Co-authored-by: marioevz <[email protected]>
…thereum#3699)

* Refactor Account into a test-type.

* First try

* Claude's attempt

* Use abstract classes for most types

* fixes

* update tests

* fix: unit tests

* suggestions for ethereum#3699 (#10)

---------

Co-authored-by: felipe <[email protected]>
…thereum#3749)

* docs(spec-specs): keep EIP branches off the Bogota docstring

Every EIP branch that rewrites the fork docstring conflicts with every other one when the devnet workflow merges them. EIP branches now leave it as it is, and an EIP adds its line under Changes when it lands here.

* chore(spec-specs): drop the Bogota docstring comment

The rule lives in the implement-eip skill, which is where contributors and agents read it.
ethereum#3676)

* feat(tests): cover BAL same-index nonce keep and code replace (ethereum#3654)

* feat(tests): cover BAL same-index nonce keep and code replace

Add a post-execution two-call fixture that CREATEs then value-CALLs at
one block access index, hitting the previously untested keep/replace
branches in add_nonce_change and add_code_change.

Co-authored-by: Cursor <[email protected]>

* style(tests): format same-index BAL coverage test

Co-authored-by: Cursor <[email protected]>

* refactor(tests): reach the same-index BAL branches with one call per predeploy

* chore(tests): fix the eip7928 missed_lines entry and its re-verify command

* chore(skills): update checklist skill wording for better results

---------

Co-authored-by: Cursor <[email protected]>
Co-authored-by: fselmo <[email protected]>

* refactor(spec-specs): remove unreachable except in calculate_memory_gas_cost (ethereum#3651)

* new(tests): precompile boundary warmth and 7702 authority SELFDESTRUCT

Add two coverage probes derived from cross-client code comparison:

- Call opcodes against addresses adjacent to the precompile ranges
  (0x00, 0x12, 0xff, 0x101, 0x1ff, and 0x100 with a high byte set) must
  pay the cold account access cost. Clients encode the pre-warmed
  precompile set as an explicit set, a numeric range, or a predicate.
- An authority materialised by a set-code authorization in the same
  transaction executes SELFDESTRUCT through its delegate. It is not a
  same-transaction contract creation, so only its balance moves and the
  nonce and delegation designator stay.

All clients agree with the specification on both.

* refactor(tests): use fork-aware utils & increase fork cov; param existing

* feat(tests): add log and BAL expectations when relevant EIPs enabled

* chore(tests): clarity and further pins for readability and tightening

* Apply suggestion from @spencer-tb

Co-authored-by: spencer <[email protected]>

* chore: update docstring based on latest pin added

---------

Co-authored-by: shubham shinde <[email protected]>
Co-authored-by: Cursor <[email protected]>
Co-authored-by: fselmo <[email protected]>
Co-authored-by: kenny-ish <[email protected]>
Co-authored-by: spencer <[email protected]>
…reum#2384)

* feat(spec): abstract py-ecc implementation detail from EIP-2537

* refactor(spec-specs): name the BLS12-381 input error

The precompiles caught every ValueError, which would also turn a py-ecc internal error or a caller bug into InvalidParameter. They now catch only InvalidInputError, raised for invalid field elements, off-curve points and failed subgroup checks.

* refactor(spec-specs): dedupe BLS12-381 decoding checks

The field-element range check and the subgroup check are each written once, in shared decoders, instead of in every operation. The precompiles also drop bytes() wrappers that did nothing and slice scalars directly, since the input length is already checked.

* perf(spec-specs): restore the BLS12-381 point decoding cache

Dropping the lru_cache made filling the EIP-2537 tests about four times slower, since MSM and pairing inputs repeat points and each repeat redid the subgroup check. The cache now sits on the crypto decoders, keyed on the raw bytes and the subgroup flag.

* refactor(spec-specs): use ethereum.crypto BLS12-381 in Bogota

Bogota's precompiles were an unchanged copy of Amsterdam's, so this copies over the migrated versions.

---------

Co-authored-by: fselmo <[email protected]>
* feat(tests): Add worst-case SSTORE test

* refactor(test-benchmark): simplify sparse-slot SSTORE benchmark

---------

Co-authored-by: LouisTsai <[email protected]>
Conflict markers are committed as-is; resolved in the follow-up commit.

Co-Authored-By: Claude <claude-fable-5-1>
Keep the fork's static-only test workflow and carry the Monad reserve
balance revert into the tx_value parametrized 7702 self-destruct test.

Co-Authored-By: Claude <claude-fable-5-1>
Join the imports and settle the formatting the hygiene lint compares
across neighbouring forks; restore MONAD_NINE's SSTORE refund comments.

Co-Authored-By: Claude <claude-fable-5-1>
Monad refunds no gas, so the sender's relative balance expectation
drops by the whole gas limit on the Monad forks.

Co-Authored-By: Claude <claude-fable-5-1>
@pdobacz
pdobacz requested review from QEDK and mijovic as code owners October 13, 2026 06:50
Comment thread packages/testing/src/execution_testing/test_types/account_types.py
Comment thread packages/testing/src/execution_testing/specs/state.py
@pdobacz
pdobacz merged commit d3cb629 into forks/monad_nine Oct 14, 2026
19 checks passed
@pdobacz
pdobacz deleted the from-upstream branch October 14, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.