[PARKED] EIP-8198: make slot-duration changes schedule-driven - #4
[PARKED] EIP-8198: make slot-duration changes schedule-driven#4chugarchugarr wants to merge 6 commits into
Conversation
396ac9d to
577ff91
Compare
577ff91 to
396028d
Compare
|
Final exact-head proof is green: https://github.com/chugarchugarr/execution-specs/actions/runs/33028230600 @CarlBeek @barnabemonnot — requesting one narrow review of the execution-layer property: after the existing 12s→10s reference implementation, can a later synthetic 10s→6s era be expressed through schedule data without another duration-specific execution path while preserving the intended wall-clock behavior? The synthetic six-second era is test data only. This does not propose six-second activation without EIP-8198's consensus-layer performance work. Canonical evidence boundary: chugarchugarr/-x402-resolution-receipt#2 |
|
Added a second synthetic future duration so the claim is no longer only 10s -> 6s: current head The final added test content passes the repository-pinned Ruff formatter and focused pytest in run https://github.com/chugarchugarr/execution-specs/actions/runs/33325824901. Full fork-native workflows on the PR head are still running/queued. The review question stays narrow: does this establish the EL property that later slot-duration changes can remain schedule data rather than require another duration-specific branch? |
4f748a0 to
b95caf4
Compare
108aee1 to
47edf92
Compare
* feat(tests): add type-0 transaction RLP validity tests
Port the core malformation classes of the legacy TransactionTests
suites (ttWrongRLP, ttNonce, ttValue, ttRSValue, ttVValue, ttAddress),
which were never converted because the ported-static pipeline only
handles state-test fillers and the raw malformed bytes cannot
round-trip through a structured transaction model.
A local RLP encoder builds each corruption deliberately, since a
correct encoder cannot emit non-canonical forms: per-field leading
zeros, 33-byte field overflows, 19 and 21 byte addresses, fields
encoded as lists, structural corruptions of the outer list (truncation,
trailing bytes, wrong element counts, header size mismatches, size
with leading zeros), and well-encoded but invalid signature values.
A valid re-encoded control case anchors the encoder to the framework's
byte-exact output.
The transaction_test fixture format records the declared exception
without consulting the transition tool, so all 30 cases were verified
externally by feeding the generated fixture bytes through EELS
decode_transaction, recover_sender and validate_transaction at
Frontier, London and Cancun: every invalid vector is rejected and the
control is accepted with the matching sender. Notably the gas limit
and gas price are unbounded scalars in the spec, so their oversized
encodings are valid at the transaction level; the overflow cases cover
the 256-bit bounded fields (nonce, value, r, s) only.
* fix(tests): accept client-divergent transaction RLP exceptions
Declare exception lists where clients legitimately report different
errors for the same malformed transaction:
- `header_declares_less`: the mutation leaves both a truncated final
field and a trailing byte at the top level, so clients report it as
either an EOF or a size error.
- `v_29`: post EIP-155 clients may derive a chain id from any v other
than 27 or 28 and reject the mismatch instead of the signature, as
already documented in `test_bad_v_r_s`.
* chore(tests): correct the transaction field overflow docstring
The nonce is decoded as a 256-bit scalar by the spec; the 64-bit bound
is an EIP-2681 validation rule, not a decoding one. Also note that the
signature v is a bounded 256-bit field whose oversized encoding is
uncovered only because no field-specific decoding exception exists.
* feat(tests): add r and s field-as-list transaction RLP cases
Extend `test_field_as_list` to the signature r and s fields, porting
`TRANSCT_rvalue_GivenAsListCopier` and `TRANSCT_svalue_GivenAsListCopier`
with the same `RLP_INVALID_SIGNATURE_R`/`_S` exceptions the legacy
suite declares. The gas price and v fields remain uncovered for lack
of a field-specific decoding exception.
* feat(tests): add a non-canonical single-byte transaction RLP case
Encode the single-byte nonce payload behind a one-byte string header
(0x8101) instead of as the byte itself. This ports the
`RLPIncorrectByteEncoding{00,01,127}Copier` legacy tests, which corrupt
the nonce this way and declare `RLP_LEADING_ZEROS_NONCE_SIZE`.
* feat(tests): add a data size leading zeros transaction RLP case
Encode the size of the data field's long-form string header with a
leading zero byte, porting `RLPArrayLengthWithFirstZerosCopier` with
the `RLP_LEADING_ZEROS_DATA_SIZE` exception it declares. This covers
the string-header variant of the list-header case already tested by
the `list_size_leading_zeros` mutation.
* feat(tests): add a zero v transaction signature case
A zero v is well-encoded (empty payload) but is neither 27, 28 nor an
EIP-155 value. Declare `INVALID_CHAINID` as an acceptable alternative
for the same reason as the other invalid v cases: post EIP-155 clients
may derive a chain id from any v other than 27 or 28.
* chore(tests): cite more covered legacy transaction test fillers
Add `ported_from` references for legacy fillers whose malformation
class is already exercised by an existing case:
- Leading zeros: the `tt{Nonce,GasPrice,GasLimit,Value}` zero-prefixed
fillers and the `TRANSCT_*_Prefixed0000` copiers.
- Overflow: the `TRANSCT_{r,s}value_TooLarge` copiers.
- Address size: `AddressMoreThan20` and the `TRANSCT_to_*` copiers.
- Field as list: the remaining `TRANSCT_*_GivenAsList` copiers.
- Structure: `RLPTransactionGivenAsArray`, matching the
`tx_as_byte_string` mutation.
All referenced fillers were inspected at the pinned commit to confirm
the corruption and declared exception match the covering case.
* fix(tests): fund only senders that send in transaction RLP tests
In execute mode, `pre.fund_eoa()` defers the funding amount until the
EOA sends a transaction; an EOA that never sends one fails the run
with "Sender balance must be set before sending". The senders of the
corrupted transactions never send: only their raw serialization is
submitted, expecting rejection. Fund them with `amount=0` so execute
mode derives an address without scheduling a funding transaction.
The signing keys are derived from the account content, so the
corrupted vectors' bytes change; all vectors were re-verified against
EELS decoding and validation at Frontier, London and Cancun.
* chore(tests): mark transaction RLP tests as inclusion tests
Each case asserts whether one transaction can be included in a block,
which is what the `inclusion_test` marker denotes.
* fix(tests): accept a type error for a transaction given as a byte string
EIP-2718 reads a byte string in the transaction list as a typed
transaction, so from Berlin on the corruption is reported as an
unsupported transaction type rather than an RLP header error. Verified
against EELS decoding at Frontier, Berlin and Cancun.
---------
Co-authored-by: danceratopz <danceratopz@gmail.com>
No spec-specific constants were useful to add here. This may change but the import from the relevant spec is preferred over adding them here if they are not BALs specific.
47edf92 to
4bef25e
Compare
ethereum#3490) * feat(tests): pin cross-frame state gas refund placement and settlement * feat(tests): EIP-8037 cross-frame refund split across a child's own spill Test that one frame's refund both repays a different slot's borrow and puts the excess in the reservoir, that the split state merges cleanly on success, and that it is fully unwound on revert and halt. * chore(tests): use fork transaction gas limit cap, not constant val * fix: apply comments from PR ethereum#3490 --------- Co-authored-by: fselmo <fselmo2@gmail.com>
4bef25e to
26473fe
Compare
26473fe to
739c870
Compare
Status — PARKED / evidence-only
This PR is retained as an executable generality and falsification proof for the pending schedule-driven EIP-8198 direction. It is not requesting merge or protocol acceptance while
ethereum/EIPs#12217remains unresolved.Current comparison boundary:
eip8198-refresh-base=e5b6e3b5ccd68eb47f2cba35da16cd2b240cb8b882acb3e5559fa1e18559ac12fd097cc62f8260d1Current exact-head validation:
33466789390checks out exact head82acb3e5559fa1e18559ac12fd097cc62f8260d1just static— PASSjust spec-tools— PASS (22 passed; 32 warnings)tests/evm_tools/eip8198_quick_slotssuite — PASS (12 passed)e5b6e3b5ccd68eb47f2cba35da16cd2b240cb8b8remains exactly 1 commit / 8 filesValidation run: https://github.com/chugarchugarr/execution-specs/actions/runs/33466789390
The previous exact-head validation artifact at
4f748a001c772e643b4a7314c70656b65c06f053, including run33326674593, remains historical evidence only and is not being represented as current-head CI.CI provenance
self-hosted-ghrwithsize-l-x64,size-xl-x64, andsize-gigachungus-x64What the proof tests
The executable claim is architectural: repeated synthetic duration eras can use shared duration/transition machinery without adding duration-specific execution branches.
The historical reference behavior is the 12s -> 10s implementation. Synthetic 10s -> 8s -> 6s entries are test data only; they are not a proposal to activate 8- or 6-second slots without the consensus-layer performance work EIP-8198 requires.
The candidate tests that:
Why it remains unresolved
There are two EIP-8198 surfaces that must not be collapsed: the published draft and the still-open author PR
ethereum/EIPs#12217, whose schedule-driven direction this experiment was built to test. Until that protocol direction resolves, this remains a falsification artifact rather than an upstream implementation claim.If
ethereum/EIPs#12217remains the intended direction, the narrow review question is: does this proof correctly establish the repeated-era execution-layer invariant, and should persistent base-fee responsiveness use active-duration / pre-schedule-duration rather than new-duration / old-duration after the first transition?