diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dbbee90979f..4c06b34800d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -57,7 +57,7 @@ Users can select any of the artifacts depending on their testing needs for their - ๐Ÿž Fix bug in ported-from plugin and coverage script that made PRs fail with modified tests that contained no ported tests ([#1661](https://github.com/ethereum/execution-spec-tests/pull/1661)). - ๐Ÿ”€ Refactor the `click`-based CLI interface used for pytest-based commands (`fill`, `execute`, `consume`) to make them more extensible ([#1654](https://github.com/ethereum/execution-spec-tests/pull/1654)). - ๐Ÿ”€ Split `src/ethereum_test_types/types.py` into several files to improve code organization ([#1665](https://github.com/ethereum/execution-spec-tests/pull/1665)). -- โœจ Added automatic checklist generation for every EIP inside of the `tests` folder. The checklist is appended to each EIP in the documentation in the "Test Case Reference" section ([#1679](https://github.com/ethereum/execution-spec-tests/pull/1679)). +- โœจ Added automatic checklist generation for every EIP inside of the `tests` folder. The checklist is appended to each EIP in the documentation in the "Test Case Reference" section ([#1679](https://github.com/ethereum/execution-spec-tests/pull/1679), [#1718](https://github.com/ethereum/execution-spec-tests/pull/1718)). ### ๐Ÿงช Test Cases diff --git a/docs/writing_tests/checklist_templates/eip_testing_checklist_template.md b/docs/writing_tests/checklist_templates/eip_testing_checklist_template.md index 04751ebe2c9..52e0c9efbd5 100644 --- a/docs/writing_tests/checklist_templates/eip_testing_checklist_template.md +++ b/docs/writing_tests/checklist_templates/eip_testing_checklist_template.md @@ -37,18 +37,18 @@ If the opcode execution can expand the memory size, either by writing to memory | ID | Description | Status | Tests | | ------------------------------------------------ | ---------------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/mem_exp/zero_bytes_zero_offset` | Zero bytes expansion with zero-offset. | | | -| `new_opcode/test/mem_exp/zero_bytes_max_offset` | Zero bytes expansion with 2\*\*256-1 offset. | | | -| `new_opcode/test/mem_exp/single_byte` | Single byte expansion. | | | -| `new_opcode/test/mem_exp/31_bytes` | 31 bytes expansion. | | | -| `new_opcode/test/mem_exp/32_bytes` | 32 bytes expansion. | | | -| `new_opcode/test/mem_exp/33_bytes` | 33 bytes expansion. | | | -| `new_opcode/test/mem_exp/64_bytes` | 64 bytes expansion. | | | -| `new_opcode/test/mem_exp/2_32_minus_one_bytes` | `2**32-1` bytes expansion. | | | -| `new_opcode/test/mem_exp/2_32_bytes` | 2\*\*32 bytes expansion. | | | -| `new_opcode/test/mem_exp/2_64_minus_one_bytes` | 2\*\*64-1 bytes expansion. | | | -| `new_opcode/test/mem_exp/2_64_bytes` | 2\*\*64 bytes expansion. | | | -| `new_opcode/test/mem_exp/2_256_minus_one_bytes` | 2\*\*256-1 bytes expansion (Should always result in Out-of-gas). | | | +| `opcode/test/mem_exp/zero_bytes_zero_offset` | Zero bytes expansion with zero-offset. | | | +| `opcode/test/mem_exp/zero_bytes_max_offset` | Zero bytes expansion with 2\*\*256-1 offset. | | | +| `opcode/test/mem_exp/single_byte` | Single byte expansion. | | | +| `opcode/test/mem_exp/31_bytes` | 31 bytes expansion. | | | +| `opcode/test/mem_exp/32_bytes` | 32 bytes expansion. | | | +| `opcode/test/mem_exp/33_bytes` | 33 bytes expansion. | | | +| `opcode/test/mem_exp/64_bytes` | 64 bytes expansion. | | | +| `opcode/test/mem_exp/2_32_minus_one_bytes` | `2**32-1` bytes expansion. | | | +| `opcode/test/mem_exp/2_32_bytes` | 2\*\*32 bytes expansion. | | | +| `opcode/test/mem_exp/2_64_minus_one_bytes` | 2\*\*64-1 bytes expansion. | | | +| `opcode/test/mem_exp/2_64_bytes` | 2\*\*64 bytes expansion. | | | +| `opcode/test/mem_exp/2_256_minus_one_bytes` | 2\*\*256-1 bytes expansion (Should always result in Out-of-gas). | | | #### Stack @@ -58,7 +58,7 @@ If the opcode pushes one or more items to the stack, and the opcode pushes more | ID | Description | Status | Tests | | -------------------------------- | --------------- | ------ | ----- | -| `new_opcode/test/stack_overflow` | Stack Overflow. | | | +| `opcode/test/stack_overflow` | Stack Overflow. | | | ##### Stack Underflow @@ -66,7 +66,7 @@ If the opcode pops one or more items to the stack, or it has a minimum stack hei | ID | Description | Status | Tests | | --------------------------------- | ---------------- | ------ | ----- | -| `new_opcode/test/stack_underflow` | Stack Underflow. | | | +| `opcode/test/stack_underflow` | Stack Underflow. | | | ##### Stack Complex Operations @@ -74,9 +74,9 @@ If opcode performs stack operations more complex than simple pop/push (e.g. the | ID | Description | Status | Tests | | ------------------------------------------------------------- | -------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/stack_complex_operations/stack_heights/zero` | Operation on an empty stack (Potential stack-underflow). | | | -| `new_opcode/test/stack_complex_operations/stack_heights/odd` | Operation on a stack with an odd height. | | | -| `new_opcode/test/stack_complex_operations/stack_heights/even` | Operation on a stack with an even height. | | | +| `opcode/test/stack_complex_operations/stack_heights/zero` | Operation on an empty stack (Potential stack-underflow). | | | +| `opcode/test/stack_complex_operations/stack_heights/odd` | Operation on a stack with an odd height. | | | +| `opcode/test/stack_complex_operations/stack_heights/even` | Operation on a stack with an even height. | | | ##### Stack Manipulation With Data Portion Variables @@ -84,9 +84,9 @@ If the opcode contains variables in its data portion, for each variable `n` of t | ID | Description | Status | Tests | | ------------------------------------------------------------ | ------------------ | ------ | ----- | -| `new_opcode/test/stack_complex_operations/variable_n/top` | Top stack item. | | | -| `new_opcode/test/stack_complex_operations/variable_n/bottom` | Bottom stack item. | | | -| `new_opcode/test/stack_complex_operations/variable_n/middle` | Middle stack item. | | | +| `opcode/test/stack_complex_operations/data_portion_variables/top` | Top stack item. | | | +| `opcode/test/stack_complex_operations/data_portion_variables/bottom` | Bottom stack item. | | | +| `opcode/test/stack_complex_operations/data_portion_variables/middle` | Middle stack item. | | | #### Execution context @@ -98,7 +98,7 @@ Verify opcode operation in a subcall frame originated from a `CALL` opcode. | ID | Description | Status | Tests | | ---------------------------------------- | ----------- | ------ | ----- | -| `new_opcode/test/execution_context/call` | `CALL`. | | | +| `opcode/test/execution_context/call` | `CALL`. | | | ##### `STATICCALL` @@ -106,9 +106,9 @@ Verify opcode operation in a subcall frame originated from a `STATICCALL` opcode | ID | Description | Status | Tests | | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | ----- | -| `new_opcode/test/execution_context/staticcall/ban_check` | Verify exceptional abort if the opcode attempts to modify the code, storage or balance of an account. | | | -| `new_opcode/test/execution_context/staticcall/ban_no_modification` | If the opcode is completely banned from static contexts, verify that even when its inputs would not cause any account modification, the opcode still results in exceptional abort of the execution (e.g. `PAY` with zero value, or `SSTORE` to the value it already has in the storage). | | | -| `new_opcode/test/execution_context/staticcall/sub_calls` | Verify sub-calls using other opcodes (e.g. `CALL`, `DELEGATECALL`, etc) also results in the same exceptional abort behavior. | | | +| `opcode/test/execution_context/staticcall/ban_check` | Verify exceptional abort if the opcode attempts to modify the code, storage or balance of an account. | | | +| `opcode/test/execution_context/staticcall/ban_no_modification` | If the opcode is completely banned from static contexts, verify that even when its inputs would not cause any account modification, the opcode still results in exceptional abort of the execution (e.g. `PAY` with zero value, or `SSTORE` to the value it already has in the storage). | | | +| `opcode/test/execution_context/staticcall/sub_calls` | Verify sub-calls using other opcodes (e.g. `CALL`, `DELEGATECALL`, etc) also results in the same exceptional abort behavior. | | | ##### `DELEGATECALL` @@ -116,10 +116,10 @@ Verify opcode operation in a subcall frame originated from a `DELEGATECALL` opco | ID | Description | Status | Tests | | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/execution_context/delegatecall` | `DELEGATECALL`. | | | -| `new_opcode/test/execution_context/delegatecall/storage` | If the opcode modifies the storage of the account currently executing it, verify that only the account that is delegating execution is the one that has its storage modified. | | | -| `new_opcode/test/execution_context/delegatecall/balance` | If the opcode modifies the balance of the account currently executing it, verify that only the account that is delegating execution is the one that has its balance modified. | | | -| `new_opcode/test/execution_context/delegatecall/code` | If the opcode modifies the code of the account currently executing it, verify that only the account that is delegating execution is the one that has its code modified. | | | +| `opcode/test/execution_context/delegatecall` | `DELEGATECALL`. | | | +| `opcode/test/execution_context/delegatecall/storage` | If the opcode modifies the storage of the account currently executing it, verify that only the account that is delegating execution is the one that has its storage modified. | | | +| `opcode/test/execution_context/delegatecall/balance` | If the opcode modifies the balance of the account currently executing it, verify that only the account that is delegating execution is the one that has its balance modified. | | | +| `opcode/test/execution_context/delegatecall/code` | If the opcode modifies the code of the account currently executing it, verify that only the account that is delegating execution is the one that has its code modified. | | | ##### `CALLCODE` @@ -127,7 +127,7 @@ Verify opcode operation in a subcall frame originated from a `CALLCODE` opcode. | ID | Description | Status | Tests | | -------------------------------------------- | ----------- | ------ | ----- | -| `new_opcode/test/execution_context/callcode` | `CALLCODE`. | | | +| `opcode/test/execution_context/callcode` | `CALLCODE`. | | | ##### Initcode @@ -135,10 +135,10 @@ Verify opcode behaves as expected when running during the initcode phase of cont | ID | Description | Status | Tests | | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/execution_context/initcode/behavior` | Initcode operation. | | | -| `new_opcode/test/execution_context/initcode/behavior/tx` | Initcode of a contract creating transaction. | | | -| `new_opcode/test/execution_context/initcode/behavior/opcode` | Initcode of a contract creating opcode (including itself if opcode creates a contract). | | | -| `new_opcode/test/execution_context/initcode/reentry` | Initcode re-entry: using the same initcode and same address (e.g. CREATE2->REVERT->CREATE2). | | | +| `opcode/test/execution_context/initcode/behavior` | Initcode operation. | | | +| `opcode/test/execution_context/initcode/behavior/tx` | Initcode of a contract creating transaction. | | | +| `opcode/test/execution_context/initcode/behavior/opcode` | Initcode of a contract creating opcode (including itself if opcode creates a contract). | | | +| `opcode/test/execution_context/initcode/reentry` | Initcode re-entry: using the same initcode and same address (e.g. CREATE2->REVERT->CREATE2). | | | ##### Set-code Delegated Account @@ -146,7 +146,7 @@ Verify opcode operations are applied to the set-code account and do not affect t | ID | Description | Status | Tests | | -------------------------------------------- | --------------------------- | ------ | ----- | -| `new_opcode/test/execution_context/set_code` | Set-code delegated account. | | | +| `opcode/test/execution_context/set_code` | Set-code delegated account. | | | ##### Transaction Context @@ -154,7 +154,7 @@ If opcode changes behavior depending on particular transaction properties, test | ID | Description | Status | Tests | | ---------------------------------------------- | ------------------------------------- | ------ | ----- | -| `new_opcode/test/execution_context/tx_context` | Transaction-context dependent opcode. | | | +| `opcode/test/execution_context/tx_context` | Transaction-context dependent opcode. | | | ##### Block Context @@ -162,7 +162,7 @@ If opcode changes behavior depending on particular block properties, test using | ID | Description | Status | Tests | | ------------------------------------------------- | ------------------------------- | ------ | ----- | -| `new_opcode/test/execution_context/block_context` | Block-context dependent opcode. | | | +| `opcode/test/execution_context/block_context` | Block-context dependent opcode. | | | #### Return data @@ -170,8 +170,8 @@ Verify proper return data buffer overwriting if the opcode is meant to interact | ID | Description | Status | Tests | | -------------------------------------------- | -------------------------------------- | ------ | ----- | -| `new_opcode/test/return_data/buffer/current` | Return buffer at current call context. | | | -| `new_opcode/test/return_data/buffer/parent` | Return buffer at parent call context. | | | +| `opcode/test/return_data/buffer/current` | Return buffer at current call context. | | | +| `opcode/test/return_data/buffer/parent` | Return buffer at parent call context. | | | #### Gas Usage @@ -181,7 +181,7 @@ Verify gas usage affectation of each stack argument or memory input consumed by | ID | Description | Status | Tests | | ---------------------------------- | --------------------------- | ------ | ----- | -| `new_opcode/test/gas_usage/normal` | Normal operation gas usage. | | | +| `opcode/test/gas_usage/normal` | Normal operation gas usage. | | | ##### Memory Expansion @@ -189,7 +189,7 @@ Verify that the memory expansion correctly follows the gas calculation. | ID | Description | Status | Tests | | -------------------------------------------- | ----------------- | ------ | ----- | -| `new_opcode/test/gas_usage/memory_expansion` | Memory expansion. | | | +| `opcode/test/gas_usage/memory_expansion` | Memory expansion. | | | ##### Out-Of-Gas @@ -197,8 +197,8 @@ Verify that attempting to execute the opcode when gas available is 1 less than t | ID | Description | Status | Tests | | ------------------------------------------------ | ----------------------------------- | ------ | ----- | -| `new_opcode/test/gas_usage/out_of_gas_execution` | Out-of-gas due to opcode inputs. | | | -| `new_opcode/test/gas_usage/out_of_gas_memory` | Out-of-gas due to memory expansion. | | | +| `opcode/test/gas_usage/out_of_gas_execution` | Out-of-gas due to opcode inputs. | | | +| `opcode/test/gas_usage/out_of_gas_memory` | Out-of-gas due to memory expansion. | | | ##### Order-of-operations @@ -206,8 +206,8 @@ If the opcode requires different gas stipends for other operations (e.g. contrac | ID | Description | Status | Tests | | ----------------------------------------------------- | ------------------------------------------------------------------ | ------ | ----- | -| `new_opcode/test/gas_usage/order_of_operations/exact` | Success using the exact amount of gas required for the stipend. | | | -| `new_opcode/test/gas_usage/order_of_operations/oog` | OOG with a 1-gas-difference from the gas required for the stipend. | | | +| `opcode/test/gas_usage/order_of_operations/exact` | Success using the exact amount of gas required for the stipend. | | | +| `opcode/test/gas_usage/order_of_operations/oog` | OOG with a 1-gas-difference from the gas required for the stipend. | | | #### Terminating opcode @@ -215,9 +215,9 @@ If an opcode is terminating, meaning it results in the current call context to e | ID | Description | Status | Tests | | ------------------------------------------------- | --------------------------- | ------ | ----- | -| `new_opcode/test/terminating/scenarios/top_level` | Top-level call termination. | | | -| `new_opcode/test/terminating/scenarios/sub_level` | Sub-level call termination. | | | -| `new_opcode/test/terminating/scenarios/initcode` | Initcode termination. | | | +| `opcode/test/terminating/scenarios/top_level` | Top-level call termination. | | | +| `opcode/test/terminating/scenarios/sub_level` | Sub-level call termination. | | | +| `opcode/test/terminating/scenarios/initcode` | Initcode termination. | | | #### Aborting/Reverting opcode @@ -225,11 +225,11 @@ If the terminating opcode is meant to rollback the executing call frame, verify | ID | Description | Status | Tests | | ------------------------------------------------ | ------------------- | ------ | ----- | -| `new_opcode/test/terminating/rollback/balance` | Balance changes. | | | -| `new_opcode/test/terminating/rollback/storage` | Storage changes. | | | -| `new_opcode/test/terminating/rollback/contracts` | Contract creations. | | | -| `new_opcode/test/terminating/rollback/nonce` | Nonce increments. | | | -| `new_opcode/test/terminating/rollback/logs` | Log events. | | | +| `opcode/test/terminating/rollback/balance` | Balance changes. | | | +| `opcode/test/terminating/rollback/storage` | Storage changes. | | | +| `opcode/test/terminating/rollback/contracts` | Contract creations. | | | +| `opcode/test/terminating/rollback/nonce` | Nonce increments. | | | +| `opcode/test/terminating/rollback/logs` | Log events. | | | #### Out-of-bounds checks @@ -237,8 +237,8 @@ If the opcode has out-of-bounds conditions in its parameters/inputs. | ID | Description | Status | Tests | | --------------------------------------------------- | --------------------------------- | ------ | ----- | -| `new_opcode/test/out_of_bounds/verify/max` | Max value for each parameter. | | | -| `new_opcode/test/out_of_bounds/verify/max_plus_one` | Max value + 1 for each parameter. | | | +| `opcode/test/out_of_bounds/verify/max` | Max value for each parameter. | | | +| `opcode/test/out_of_bounds/verify/max_plus_one` | Max value + 1 for each parameter. | | | #### Exceptional Abort @@ -246,7 +246,7 @@ If the opcode has conditions, either inputs or execution context states, that sh | ID | Description | Status | Tests | | ----------------------------------- | ----------------------------- | ------ | ----- | -| `new_opcode/test/exceptional_abort` | Exceptional abort conditions. | | | +| `opcode/test/exceptional_abort` | Exceptional abort conditions. | | | #### Data portion @@ -254,9 +254,9 @@ If an opcode has a data portion, meaning the `N` bytes following the opcode in t | ID | Description | Status | Tests | | ---------------------------------------- | -------------------------------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/data_portion/all_zeros` | All zeros data portion. | | | -| `new_opcode/test/data_portion/max_value` | Max value data portion (`2**N-1` where `N` is the bit size of the data portion). | | | -| `new_opcode/test/data_portion/jump` | Jump into the data portion. | | | +| `opcode/test/data_portion/all_zeros` | All zeros data portion. | | | +| `opcode/test/data_portion/max_value` | Max value data portion (`2**N-1` where `N` is the bit size of the data portion). | | | +| `opcode/test/data_portion/jump` | Jump into the data portion. | | | #### Contract creation @@ -268,7 +268,7 @@ Verify contract is created at the expected address given multiple inputs. | ID | Description | Status | Tests | | ------------------------------------------- | -------------------- | ------ | ----- | -| `new_opcode/test/contract_creation/address` | Address calculation. | | | +| `opcode/test/contract_creation/address` | Address calculation. | | | ##### Creation Failure @@ -276,9 +276,9 @@ The contract creation fails given the listed conditions. | ID | Description | Status | Tests | | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/contract_creation/failure/oog` | Out-of-gas when available gas is less than minimum contract creation stipend. | | | -| `new_opcode/test/contract_creation/failure/insufficient_value` | Opcode has a value parameter and the caller does not have enough funds. | | | -| `new_opcode/test/contract_creation/failure/collision` | Creation would result in an address collision with an existing contract or EOA-delegated address. | | | +| `opcode/test/contract_creation/failure/oog` | Out-of-gas when available gas is less than minimum contract creation stipend. | | | +| `opcode/test/contract_creation/failure/insufficient_value` | Opcode has a value parameter and the caller does not have enough funds. | | | +| `opcode/test/contract_creation/failure/collision` | Creation would result in an address collision with an existing contract or EOA-delegated address. | | | ##### Recursive Contract Creation @@ -286,14 +286,14 @@ Opcode is used to attempt to recreate a contract that is currently mid-creation | ID | Description | Status | Tests | | --------------------------------------------- | --------------------------------------------- | ------ | ----- | -| `new_opcode/test/contract_creation/recursive` | Recursive contract creation using the opcode. | | | +| `opcode/test/contract_creation/recursive` | Recursive contract creation using the opcode. | | | #### Fork transition | ID | Description | Status | Tests | | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_opcode/test/fork_transition/invalid` | Exceptional abort if executed before its activation fork/after its deactivation fork. | | | -| `new_opcode/test/fork_transition/at` | Verify correct opcode behavior at transition block, in the case of opcodes which behavior depends on current or parent block information. | | | +| `opcode/test/fork_transition/invalid` | Exceptional abort if executed before its activation fork/after its deactivation fork. | | | +| `opcode/test/fork_transition/at` | Verify correct opcode behavior at transition block, in the case of opcodes which behavior depends on current or parent block information. | | | ### Framework Changes @@ -319,7 +319,7 @@ Verify precompile operation when called using the `CALL` opcode. | ID | Description | Status | Tests | | ------------------------------------------ | ----------- | ------ | ----- | -| `new_precompile/test/call_contexts/normal` | `CALL`. | | | +| `precompile/test/call_contexts/normal` | `CALL`. | | | ##### `DELEGATECALL` @@ -327,7 +327,7 @@ Verify precompile operation when called using the `DELEGATECALL` opcode. | ID | Description | Status | Tests | | -------------------------------------------- | --------------- | ------ | ----- | -| `new_precompile/test/call_contexts/delegate` | `DELEGATECALL`. | | | +| `precompile/test/call_contexts/delegate` | `DELEGATECALL`. | | | ##### `STATICCALL` @@ -337,7 +337,7 @@ If the precompile is stateful, meaning calling it affects its storage, this call | ID | Description | Status | Tests | | ------------------------------------------ | ------------- | ------ | ----- | -| `new_precompile/test/call_contexts/static` | `STATICCALL`. | | | +| `precompile/test/call_contexts/static` | `STATICCALL`. | | | ##### `CALLCODE` @@ -345,7 +345,7 @@ Verify precompile operation when called using the `CALLCODE` opcode. | ID | Description | Status | Tests | | -------------------------------------------- | ----------- | ------ | ----- | -| `new_precompile/test/call_contexts/callcode` | `CALLCODE`. | | | +| `precompile/test/call_contexts/callcode` | `CALLCODE`. | | | ##### Transaction Entry-point @@ -353,7 +353,7 @@ Verify precompile behavior when it's used as `tx.to`. | ID | Description | Status | Tests | | -------------------------------------------- | -------------------------------------- | ------ | ----- | -| `new_precompile/test/call_contexts/tx_entry` | Precompile as transaction entry-point. | | | +| `precompile/test/call_contexts/tx_entry` | Precompile as transaction entry-point. | | | ##### Initcode call @@ -361,8 +361,8 @@ Verify calling the opcode during initcode execution of a new contract. | ID | Description | Status | Tests | | --------------------------------------------------- | ---------------------------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/call_contexts/initcode/CREATE` | Call from Initcode initiated from a CREATE/CREATE2 opcode. | | | -| `new_precompile/test/call_contexts/initcode/tx` | Call from Initcode initiated from a contract-creating transaction (`tx.to==None`). | | | +| `precompile/test/call_contexts/initcode/CREATE` | Call from Initcode initiated from a CREATE/CREATE2 opcode. | | | +| `precompile/test/call_contexts/initcode/tx` | Call from Initcode initiated from a contract-creating transaction (`tx.to==None`). | | | ##### Precompile as Set-code Delegated Address @@ -370,20 +370,20 @@ Test setting the precompile as a set-code delegated address, and verify no preco | ID | Description | Status | Tests | | -------------------------------------------- | --------------------------- | ------ | ----- | -| `new_precompile/test/call_contexts/set_code` | Set code delegated address. | | | +| `precompile/test/call_contexts/set_code` | Set code delegated address. | | | #### Inputs | ID | Description | Status | Tests | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/inputs/valid` | Verify combinations of valid inputs to the precompile. | | | -| `new_precompile/test/inputs/valid/boundary` | Verify all boundary values given the precompile functionality. | | | -| `new_precompile/test/inputs/valid/crypto` | If precompile performs cryptographic operations, verify behavior on all inputs that have special cryptographic properties (e.g. infinity points as inputs, or input values that result in infinity points returned). | | | -| `new_precompile/test/inputs/all_zeros` | Verify all zeros input. | | | -| `new_precompile/test/inputs/max_values` | Verify 2^N-1 where N is a single or multiple valid bit-lengths. | | | -| `new_precompile/test/inputs/invalid` | Verify combinations of invalid inputs to the precompile. | | | -| `new_precompile/test/inputs/invalid/crypto` | Inputs that fail specific mathematical or cryptographic validity checks. | | | -| `new_precompile/test/inputs/invalid/corrupted` | Inputs that are malformed/corrupted. | | | +| `precompile/test/inputs/valid` | Verify combinations of valid inputs to the precompile. | | | +| `precompile/test/inputs/valid/boundary` | Verify all boundary values given the precompile functionality. | | | +| `precompile/test/inputs/valid/crypto` | If precompile performs cryptographic operations, verify behavior on all inputs that have special cryptographic properties (e.g. infinity points as inputs, or input values that result in infinity points returned). | | | +| `precompile/test/inputs/all_zeros` | Verify all zeros input. | | | +| `precompile/test/inputs/max_values` | Verify 2^N-1 where N is a single or multiple valid bit-lengths. | | | +| `precompile/test/inputs/invalid` | Verify combinations of invalid inputs to the precompile. | | | +| `precompile/test/inputs/invalid/crypto` | Inputs that fail specific mathematical or cryptographic validity checks. | | | +| `precompile/test/inputs/invalid/corrupted` | Inputs that are malformed/corrupted. | | | #### Value Transfer @@ -393,15 +393,15 @@ If the precompile requires a minimum value (fee) to execute, either constant or | ID | Description | Status | Tests | | ---------------------------------------------- | ---------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/value_transfer/fee/under` | Calls with the required value amount minus one, expect failure. | | | -| `new_precompile/test/value_transfer/fee/exact` | Calls with the exact required amount, expect success. | | | -| `new_precompile/test/value_transfer/fee/over` | Calls with extra value than the required amount, expect success. | | | +| `precompile/test/value_transfer/fee/under` | Calls with the required value amount minus one, expect failure. | | | +| `precompile/test/value_transfer/fee/exact` | Calls with the exact required amount, expect success. | | | +| `precompile/test/value_transfer/fee/over` | Calls with extra value than the required amount, expect success. | | | ##### No-Fee Precompile If the precompile does not require any minimum value (fee) to execute. -| `new_precompile/test/value_transfer/no_fee` | Sending non-zero value does not cause an exception (unless otherwise specified by the EIP). | | | +| `precompile/test/value_transfer/no_fee` | Sending non-zero value does not cause an exception (unless otherwise specified by the EIP). | | | #### Out-of-bounds checks @@ -409,8 +409,8 @@ If the precompile has out-of-bounds conditions in its inputs. | ID | Description | Status | Tests | | ------------------------------------------------ | ----------------------------- | ------ | ----- | -| `new_precompile/test/out_of_bounds/max` | Max value for each input. | | | -| `new_precompile/test/out_of_bounds/max_plus_one` | Max value + 1 for each input. | | | +| `precompile/test/out_of_bounds/max` | Max value for each input. | | | +| `precompile/test/out_of_bounds/max_plus_one` | Max value + 1 for each input. | | | #### Input Lengths @@ -422,7 +422,7 @@ Regardless of the input requirements for the precompile. | ID | Description | Status | Tests | | ---------------------------------------- | --------------------- | ------ | ----- | -| `new_precompile/test/input_lengths/zero` | Zero-length calldata. | | | +| `precompile/test/input_lengths/zero` | Zero-length calldata. | | | ##### Static Required Input Length @@ -430,9 +430,9 @@ If the precompile has a static required input length. | ID | Description | Status | Tests | | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/input_lengths/static/correct` | Correct static-length calldata. | | | -| `new_precompile/test/input_lengths/static/too_short` | Calldata too short, where the value represents a correct but truncated input to the precompile. | | | -| `new_precompile/test/input_lengths/static/too_long` | Calldata too long, where the value represents a correct input to the precompile with padded zeros. | | | +| `precompile/test/input_lengths/static/correct` | Correct static-length calldata. | | | +| `precompile/test/input_lengths/static/too_short` | Calldata too short, where the value represents a correct but truncated input to the precompile. | | | +| `precompile/test/input_lengths/static/too_long` | Calldata too long, where the value represents a correct input to the precompile with padded zeros. | | | ##### Dynamic Required Input Length @@ -440,9 +440,9 @@ If the precompile has a variable required input-length based on a formula, test | ID | Description | Status | Tests | | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/input_lengths/dynamic/valid` | Verify correct precompile execution for valid lengths. | | | -| `new_precompile/test/input_lengths/dynamic/too_short` | Calldata too short, where the value represents a correct but truncated input to the precompile. | | | -| `new_precompile/test/input_lengths/dynamic/too_long` | Calldata too long, where the value represents a correct input to the precompile with padded zeros. | | | +| `precompile/test/input_lengths/dynamic/valid` | Verify correct precompile execution for valid lengths. | | | +| `precompile/test/input_lengths/dynamic/too_short` | Calldata too short, where the value represents a correct but truncated input to the precompile. | | | +| `precompile/test/input_lengths/dynamic/too_long` | Calldata too long, where the value represents a correct input to the precompile with padded zeros. | | | #### Gas usage @@ -452,8 +452,8 @@ If the precompile always charges the same gas cost regardless of input condition | ID | Description | Status | Tests | | ---------------------------------------------- | ------------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/gas_usage/constant/exact` | Verify exact gas consumption. | | | -| `new_precompile/test/gas_usage/constant/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | +| `precompile/test/gas_usage/constant/exact` | Verify exact gas consumption. | | | +| `precompile/test/gas_usage/constant/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | ##### Variable Gas Cost @@ -461,8 +461,8 @@ If the precompile charges variable gas cost given input conditions, test all lis | ID | Description | Status | Tests | | --------------------------------------------- | ------------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/gas_usage/dynamic/exact` | Verify exact gas consumption. | | | -| `new_precompile/test/gas_usage/dynamic/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | +| `precompile/test/gas_usage/dynamic/exact` | Verify exact gas consumption. | | | +| `precompile/test/gas_usage/dynamic/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | ##### Excessive Gas @@ -470,7 +470,7 @@ Verify spending all block gas in calls to the precompile (Use `Environment().gas | ID | Description | Status | Tests | | ----------------------------------------- | -------------------- | ------ | ----- | -| `new_precompile/test/excessive_gas_usage` | Excessive gas usage. | | | +| `precompile/test/excessive_gas_usage` | Excessive gas usage. | | | #### Fork transition @@ -480,8 +480,8 @@ Verify that calling the precompile before its activation fork results in a valid | ID | Description | Status | Tests | | ---------------------------------------------------------- | ------------------- | ------ | ----- | -| `new_precompile/test/fork_transition/before/invalid_input` | Invalid input call. | | | -| `new_precompile/test/fork_transition/before/zero_gas` | Zero-gas call. | | | +| `precompile/test/fork_transition/before/invalid_input` | Invalid input call. | | | +| `precompile/test/fork_transition/before/zero_gas` | Zero-gas call. | | | ##### Cold/Warm Precompile Address State @@ -489,8 +489,8 @@ Verify the cold/warm state of the precompile address depending on the fork activ | ID | Description | Status | Tests | | ------------------------------------------------- | ----------------------------------------------------------------- | ------ | ----- | -| `new_precompile/test/fork_transition/before/cold` | Precompile address is cold by default before the fork activation. | | | -| `new_precompile/test/fork_transition/after/warm` | Precompile address is warm by default after the fork activation. | | | +| `precompile/test/fork_transition/before/cold` | Precompile address is cold by default before the fork activation. | | | +| `precompile/test/fork_transition/after/warm` | Precompile address is warm by default after the fork activation. | | | ### Framework Changes @@ -539,7 +539,7 @@ Verify system contract operation when called using the `CALL` opcode. | ID | Description | Status | Tests | | ----------------------------------------------- | ----------- | ------ | ----- | -| `new_system_contract/test/call_contexts/normal` | `CALL`. | | | +| `system_contract/test/call_contexts/normal` | `CALL`. | | | ##### `DELEGATECALL` @@ -547,7 +547,7 @@ Verify system contract operation when called using the `DELEGATECALL` opcode. | ID | Description | Status | Tests | | ------------------------------------------------- | --------------- | ------ | ----- | -| `new_system_contract/test/call_contexts/delegate` | `DELEGATECALL`. | | | +| `system_contract/test/call_contexts/delegate` | `DELEGATECALL`. | | | ##### `STATICCALL` @@ -557,7 +557,7 @@ If the system contract is stateful, meaning calling it affects its storage, this | ID | Description | Status | Tests | | ----------------------------------------------- | ------------- | ------ | ----- | -| `new_system_contract/test/call_contexts/static` | `STATICCALL`. | | | +| `system_contract/test/call_contexts/static` | `STATICCALL`. | | | ##### `CALLCODE` @@ -565,7 +565,7 @@ Verify system contract operation when called using the `CALLCODE` opcode. | ID | Description | Status | Tests | | ------------------------------------------------- | ----------- | ------ | ----- | -| `new_system_contract/test/call_contexts/callcode` | `CALLCODE`. | | | +| `system_contract/test/call_contexts/callcode` | `CALLCODE`. | | | ##### Transaction Entry-point @@ -573,7 +573,7 @@ Verify system contract behavior when it's used as `tx.to`. | ID | Description | Status | Tests | | ------------------------------------------------- | ------------------------------------------- | ------ | ----- | -| `new_system_contract/test/call_contexts/tx_entry` | System Contract as transaction entry-point. | | | +| `system_contract/test/call_contexts/tx_entry` | System Contract as transaction entry-point. | | | ##### Initcode call @@ -581,8 +581,8 @@ Verify calling the opcode during initcode execution of a new contract. | ID | Description | Status | Tests | | -------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/call_contexts/initcode/CREATE` | Call from Initcode initiated from a CREATE/CREATE2 opcode. | | | -| `new_system_contract/test/call_contexts/initcode/tx` | Call from Initcode initiated from a contract-creating transaction (`tx.to==None`). | | | +| `system_contract/test/call_contexts/initcode/CREATE` | Call from Initcode initiated from a CREATE/CREATE2 opcode. | | | +| `system_contract/test/call_contexts/initcode/tx` | Call from Initcode initiated from a contract-creating transaction (`tx.to==None`). | | | ##### System Contract as Set-code Delegated Address @@ -592,20 +592,20 @@ If the system contract requires specific storage pre-conditions to be set for pr | ID | Description | Status | Tests | | ------------------------------------------------- | --------------------------- | ------ | ----- | -| `new_system_contract/test/call_contexts/set_code` | Set code delegated address. | | | +| `system_contract/test/call_contexts/set_code` | Set code delegated address. | | | #### Inputs | ID | Description | Status | Tests | | --------------------------------------------------- | ------------------------------------------------------------------------ | ------ | ----- | -| `new_system_contract/test/inputs/valid` | Verify combinations of valid inputs to the system contract. | | | -| `new_system_contract/test/inputs/boundary` | Verify all boundary values given the system contract functionality. | | | -| `new_system_contract/test/inputs/all_zeros` | Verify all zeros input. | | | -| `new_system_contract/test/inputs/max_values` | Verify 2^N-1 where N is a single or multiple valid bit-lengths. | | | -| `new_system_contract/test/inputs/invalid` | Verify combinations of invalid inputs to the precompile. | | | -| `new_system_contract/test/inputs/invalid/checks` | Inputs that fail validity checks. | | | -| `new_system_contract/test/inputs/invalid/crypto` | Inputs that fail specific mathematical or cryptographic validity checks. | | | -| `new_system_contract/test/inputs/invalid/corrupted` | Inputs that are malformed/corrupted. | | | +| `system_contract/test/inputs/valid` | Verify combinations of valid inputs to the system contract. | | | +| `system_contract/test/inputs/boundary` | Verify all boundary values given the system contract functionality. | | | +| `system_contract/test/inputs/all_zeros` | Verify all zeros input. | | | +| `system_contract/test/inputs/max_values` | Verify 2^N-1 where N is a single or multiple valid bit-lengths. | | | +| `system_contract/test/inputs/invalid` | Verify combinations of invalid inputs to the precompile. | | | +| `system_contract/test/inputs/invalid/checks` | Inputs that fail validity checks. | | | +| `system_contract/test/inputs/invalid/crypto` | Inputs that fail specific mathematical or cryptographic validity checks. | | | +| `system_contract/test/inputs/invalid/corrupted` | Inputs that are malformed/corrupted. | | | #### Value Transfer @@ -615,9 +615,9 @@ If the system contract requires a minimum value (fee) to execute, either constan | ID | Description | Status | Tests | | --------------------------------------------------- | ---------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/value_transfer/fee/under` | Calls with the required value amount minus one, expect failure. | | | -| `new_system_contract/test/value_transfer/fee/exact` | Calls with the exact required amount, expect success. | | | -| `new_system_contract/test/value_transfer/fee/over` | Calls with extra value than the required amount, expect success. | | | +| `system_contract/test/value_transfer/fee/under` | Calls with the required value amount minus one, expect failure. | | | +| `system_contract/test/value_transfer/fee/exact` | Calls with the exact required amount, expect success. | | | +| `system_contract/test/value_transfer/fee/over` | Calls with extra value than the required amount, expect success. | | | ##### No-Fee System Contract @@ -625,7 +625,7 @@ If the system contract does not require any minimum value (fee) to execute. | ID | Description | Status | Tests | | ------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/value_transfer/no_fee` | Sending non-zero value does not cause an exception (unless otherwise specified by the EIP). | | | +| `system_contract/test/value_transfer/no_fee` | Sending non-zero value does not cause an exception (unless otherwise specified by the EIP). | | | #### Out-of-bounds checks @@ -633,8 +633,8 @@ If the system contract has out-of-bounds conditions in its inputs. | ID | Description | Status | Tests | | ----------------------------------------------------- | ----------------------------- | ------ | ----- | -| `new_system_contract/test/out_of_bounds/max` | Max value for each input. | | | -| `new_system_contract/test/out_of_bounds/max_plus_one` | Max value + 1 for each input. | | | +| `system_contract/test/out_of_bounds/max` | Max value for each input. | | | +| `system_contract/test/out_of_bounds/max_plus_one` | Max value + 1 for each input. | | | #### Input Lengths @@ -646,7 +646,7 @@ Regardless of the input requirements for the system contract. | ID | Description | Status | Tests | | --------------------------------------------- | --------------------- | ------ | ----- | -| `new_system_contract/test/input_lengths/zero` | Zero-length calldata. | | | +| `system_contract/test/input_lengths/zero` | Zero-length calldata. | | | ##### Static Required Input Length @@ -654,9 +654,9 @@ If the system contract has a static required input length. | ID | Description | Status | Tests | | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------ | ----- | -| `new_system_contract/test/input_lengths/static/correct` | Correct static-length calldata. | | | -| `new_system_contract/test/input_lengths/static/too_short` | Calldata too short, where the value represents a correct but truncated input to the contract. | | | -| `new_system_contract/test/input_lengths/static/too_long` | Calldata too long, where the value represents a correct input to the contract with padded zeros. | | | +| `system_contract/test/input_lengths/static/correct` | Correct static-length calldata. | | | +| `system_contract/test/input_lengths/static/too_short` | Calldata too short, where the value represents a correct but truncated input to the contract. | | | +| `system_contract/test/input_lengths/static/too_long` | Calldata too long, where the value represents a correct input to the contract with padded zeros. | | | ##### Dynamic Required Input Length @@ -664,9 +664,9 @@ If the system contract has a variable required input-length based on a formula, | ID | Description | Status | Tests | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------ | ----- | -| `new_system_contract/test/input_lengths/dynamic/valid` | Verify correct system contract execution for valid lengths. | | | -| `new_system_contract/test/input_lengths/dynamic/too_short` | Calldata too short, where the value represents a correct but truncated input to the contract. | | | -| `new_system_contract/test/input_lengths/dynamic/too_long` | Calldata too long, where the value represents a correct input to the contract with padded zeros. | | | +| `system_contract/test/input_lengths/dynamic/valid` | Verify correct system contract execution for valid lengths. | | | +| `system_contract/test/input_lengths/dynamic/too_short` | Calldata too short, where the value represents a correct but truncated input to the contract. | | | +| `system_contract/test/input_lengths/dynamic/too_long` | Calldata too long, where the value represents a correct input to the contract with padded zeros. | | | #### Gas usage @@ -676,8 +676,8 @@ If the system contract always charges the same gas cost regardless of input cond | ID | Description | Status | Tests | | --------------------------------------------------- | ------------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/gas_usage/constant/exact` | Verify exact gas consumption. | | | -| `new_system_contract/test/gas_usage/constant/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | +| `system_contract/test/gas_usage/constant/exact` | Verify exact gas consumption. | | | +| `system_contract/test/gas_usage/constant/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | ##### Variable Gas Cost @@ -685,8 +685,8 @@ If the system contract charges variable gas cost given input conditions, test al | ID | Description | Status | Tests | | -------------------------------------------------- | ------------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/gas_usage/dynamic/exact` | Verify exact gas consumption. | | | -| `new_system_contract/test/gas_usage/dynamic/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | +| `system_contract/test/gas_usage/dynamic/exact` | Verify exact gas consumption. | | | +| `system_contract/test/gas_usage/dynamic/oog` | Verify exact gas consumption minus one results in out-of-gas error. | | | #### Excessive Gas Cases @@ -696,7 +696,7 @@ Verify spending all block gas in calls to system contract (Use `Environment().ga | ID | Description | Status | Tests | | -------------------------------------------------- | ------------------------ | ------ | ----- | -| `new_system_contract/test/excessive_gas/block_gas` | Exhaust block gas limit. | | | +| `system_contract/test/excessive_gas/block_gas` | Exhaust block gas limit. | | | ##### Excessive Gas Usage During System Call @@ -704,14 +704,14 @@ If possible, produce a scenario where, given all transactions executed within th | ID | Description | Status | Tests | | ---------------------------------------------------- | ----------------------------- | ------ | ----- | -| `new_system_contract/test/excessive_gas/system_call` | Excessive gas on system call. | | | +| `system_contract/test/excessive_gas/system_call` | Excessive gas on system call. | | | #### System Contract Deployment | ID | Description | Status | Tests | | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/deployment/missing` | Verify block execution behavior after fork activation if the system contract has not been deployed (Depending on the EIP, block could be invalid). | | | -| `new_system_contract/test/deployment/address` | Verify deployment transaction results in the system contract being deployed to the expected address. | | | +| `system_contract/test/deployment/missing` | Verify block execution behavior after fork activation if the system contract has not been deployed (Depending on the EIP, block could be invalid). | | | +| `system_contract/test/deployment/address` | Verify deployment transaction results in the system contract being deployed to the expected address. | | | #### Contract Variations @@ -719,7 +719,7 @@ Verify execution of the different variations of the contract for different netwo | ID | Description | Status | Tests | | ------------------------------------------------------- | -------------------------------------- | ------ | ----- | -| `new_system_contract/test/contract_variations/networks` | Different network contract variations. | | | +| `system_contract/test/contract_variations/networks` | Different network contract variations. | | | #### Contract Substitution @@ -727,11 +727,11 @@ Substitute the default system contract with a mock contract to modify its behavi | ID | Description | Status | Tests | | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | ------ | ----- | -| `new_system_contract/test/contract_substitution/return_lengths` | Modified return value lengths. | | | -| `new_system_contract/test/contract_substitution/logs` | Modified to emit logs or modified logs. | | | -| `new_system_contract/test/contract_substitution/exception` | Modified to cause an exception (e.g. invalid opcode). | | | -| `new_system_contract/test/contract_substitution/gas_limit_success` | Modified to consume 30,000,000 million gas exactly, execution should be successful. | | | -| `new_system_contract/test/contract_substitution/gas_limit_failure` | Modified to consume 30,000,001 million gas exactly, execution should fail. | | | +| `system_contract/test/contract_substitution/return_lengths` | Modified return value lengths. | | | +| `system_contract/test/contract_substitution/logs` | Modified to emit logs or modified logs. | | | +| `system_contract/test/contract_substitution/exception` | Modified to cause an exception (e.g. invalid opcode). | | | +| `system_contract/test/contract_substitution/gas_limit_success` | Modified to consume 30,000,000 million gas exactly, execution should be successful. | | | +| `system_contract/test/contract_substitution/gas_limit_failure` | Modified to consume 30,000,001 million gas exactly, execution should fail. | | | #### Fork transition @@ -739,7 +739,7 @@ Verify calling the system contract before its activation fork results in correct | ID | Description | Status | Tests | | ----------------------------------------------------------- | --------------------------------- | ------ | ----- | -| `new_system_contract/test/fork_transition/call_before_fork` | Call system contract before fork. | | | +| `system_contract/test/fork_transition/call_before_fork` | Call system contract before fork. | | | ### Framework Changes @@ -762,53 +762,53 @@ Note: Data floor gas cost affects the intrinsic validity of all transaction type | ID | Description | Status | Tests | | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/gas_limit/exact` | Provide the exact intrinsic gas as `gas_limit` value to the transaction. | | | -| `new_transaction_type/test/intrinsic_validity/gas_limit/insufficient` | Provide the exact intrinsic gas minus one as `gas_limit` value to the transaction. | | | +| `transaction_type/test/intrinsic_validity/gas_limit/exact` | Provide the exact intrinsic gas as `gas_limit` value to the transaction. | | | +| `transaction_type/test/intrinsic_validity/gas_limit/insufficient` | Provide the exact intrinsic gas minus one as `gas_limit` value to the transaction. | | | ##### Gas Fee | ID | Description | Status | Tests | | -------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/max_fee/max_priority_lower_than_max_fee` | Invalid if `tx.max_priority_fee_per_gas < tx.max_fee_per_gas`. | | | -| `new_transaction_type/test/intrinsic_validity/max_fee/max_priority_equal_to_max_fee` | Valid if `tx.max_priority_fee_per_gas == tx.max_fee_per_gas`. | | | -| `new_transaction_type/test/intrinsic_validity/max_fee/base_lower` | Invalid if `tx.max_fee_per_gas < block.base_fee_per_gas`. | | | -| `new_transaction_type/test/intrinsic_validity/max_fee/base_equal` | Valid if `tx.max_fee_per_gas < block.base_fee_per_gas`. | | | +| `transaction_type/test/intrinsic_validity/max_fee/max_priority_lower_than_max_fee` | Invalid if `tx.max_priority_fee_per_gas < tx.max_fee_per_gas`. | | | +| `transaction_type/test/intrinsic_validity/max_fee/max_priority_equal_to_max_fee` | Valid if `tx.max_priority_fee_per_gas == tx.max_fee_per_gas`. | | | +| `transaction_type/test/intrinsic_validity/max_fee/base_lower` | Invalid if `tx.max_fee_per_gas < block.base_fee_per_gas`. | | | +| `transaction_type/test/intrinsic_validity/max_fee/base_equal` | Valid if `tx.max_fee_per_gas < block.base_fee_per_gas`. | | | ##### Chain ID | ID | Description | Status | Tests | | ------------------------------------------------------- | --------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/chain_id` | Invalid if `tx.chain_id != network.chain_id`. | | | +| `transaction_type/test/intrinsic_validity/chain_id` | Invalid if `tx.chain_id != network.chain_id`. | | | ##### Nonce | ID | Description | Status | Tests | | -------------------------------------------------------------- | ------------------------------------------ | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/nonce_minus_one` | Invalid if `tx.nonce == sender.nonce - 1`. | | | -| `new_transaction_type/test/intrinsic_validity/nonce_plus_one` | Invalid if `tx.nonce == sender.nonce + 1`. | | | -| `new_transaction_type/test/intrinsic_validity/nonce_exact` | Valid if `tx.nonce == sender.nonce`. | | | +| `transaction_type/test/intrinsic_validity/nonce_minus_one` | Invalid if `tx.nonce == sender.nonce - 1`. | | | +| `transaction_type/test/intrinsic_validity/nonce_plus_one` | Invalid if `tx.nonce == sender.nonce + 1`. | | | +| `transaction_type/test/intrinsic_validity/nonce_exact` | Valid if `tx.nonce == sender.nonce`. | | | ##### To | ID | Description | Status | Tests | | ------------------------------------------------- | ------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/to` | Valid/Invalid if `tx.to == None`, depending on the EIP. | | | +| `transaction_type/test/intrinsic_validity/to` | Valid/Invalid if `tx.to == None`, depending on the EIP. | | | ##### Value | ID | Description | Status | Tests | | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/value_non_zero_insufficient_balance` | Invalid if `tx.value == 1` and `account.balance == (tx.max_fee_per_gas * tx.gas_price)`. | | | -| `new_transaction_type/test/intrinsic_validity/value_non_zero_sufficient_balance` | Valid if `tx.value == 1` and `account.balance == (tx.max_fee_per_gas * tx.gas_price) + 1`. | | | -| `new_transaction_type/test/intrinsic_validity/value_zero_insufficient_balance` | Invalid if `tx.value == 0` and `account.balance == (tx.max_fee_per_gas * tx.gas_price) - 1`. | | | -| `new_transaction_type/test/intrinsic_validity/value_zero_sufficient_balance` | Valid if `tx.value == 0` and `account.balance == (tx.max_fee_per_gas * tx.gas_price)`. | | | +| `transaction_type/test/intrinsic_validity/value_non_zero_insufficient_balance` | Invalid if `tx.value == 1` and `account.balance == (tx.max_fee_per_gas * tx.gas_price)`. | | | +| `transaction_type/test/intrinsic_validity/value_non_zero_sufficient_balance` | Valid if `tx.value == 1` and `account.balance == (tx.max_fee_per_gas * tx.gas_price) + 1`. | | | +| `transaction_type/test/intrinsic_validity/value_zero_insufficient_balance` | Invalid if `tx.value == 0` and `account.balance == (tx.max_fee_per_gas * tx.gas_price) - 1`. | | | +| `transaction_type/test/intrinsic_validity/value_zero_sufficient_balance` | Valid if `tx.value == 0` and `account.balance == (tx.max_fee_per_gas * tx.gas_price)`. | | | ##### Data | ID | Description | Status | Tests | | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/data_floor_above_intrinsic_gas_cost` | Invalid if `data_floor_cost(len(tx.data)) > tx.intrinsic_gas_cost` and `tx.gas_limit == tx.intrinsic_gas_cost`. | | | -| `new_transaction_type/test/intrinsic_validity/data_floor_above_intrinsic_gas_cost` | Valid if `data_floor_cost(len(tx.data)) > tx.intrinsic_gas_cost` and `tx.gas_limit == data_floor_cost(len(tx.data))`. | | | +| `transaction_type/test/intrinsic_validity/data_floor_above_intrinsic_gas_cost` | Invalid if `data_floor_cost(len(tx.data)) > tx.intrinsic_gas_cost` and `tx.gas_limit == tx.intrinsic_gas_cost`. | | | +| `transaction_type/test/intrinsic_validity/data_floor_above_intrinsic_gas_cost` | Valid if `data_floor_cost(len(tx.data)) > tx.intrinsic_gas_cost` and `tx.gas_limit == data_floor_cost(len(tx.data))`. | | | #### Signature @@ -816,58 +816,58 @@ Verify the transaction is correctly rejected if it contains an invalid signature | ID | Description | Status | Tests | | ----------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/signature/invalid/field_outside_curve` | V, R, S represent a value that is inside of the field but outside of the curve. | | | +| `transaction_type/test/signature/invalid/field_outside_curve` | V, R, S represent a value that is inside of the field but outside of the curve. | | | ##### V | ID | Description | Status | Tests | | --------------------------------------------------- | ---------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/signature/invalid/v/2` | `2`. | | | -| `new_transaction_type/test/signature/invalid/v/27` | `27` (Type-0 transaction valid value). | | | -| `new_transaction_type/test/signature/invalid/v/28` | `28` (Type-0 transaction valid value). | | | -| `new_transaction_type/test/signature/invalid/v/35` | `35` (Type-0 replay-protected transaction valid value for chain id 1). | | | -| `new_transaction_type/test/signature/invalid/v/36` | `36` (Type-0 replay-protected transaction valid value for chain id 1). | | | -| `new_transaction_type/test/signature/invalid/v/max` | `2**8-1`. | | | +| `transaction_type/test/signature/invalid/v/2` | `2`. | | | +| `transaction_type/test/signature/invalid/v/27` | `27` (Type-0 transaction valid value). | | | +| `transaction_type/test/signature/invalid/v/28` | `28` (Type-0 transaction valid value). | | | +| `transaction_type/test/signature/invalid/v/35` | `35` (Type-0 replay-protected transaction valid value for chain id 1). | | | +| `transaction_type/test/signature/invalid/v/36` | `36` (Type-0 replay-protected transaction valid value for chain id 1). | | | +| `transaction_type/test/signature/invalid/v/max` | `2**8-1`. | | | ##### R | ID | Description | Status | Tests | | -------------------------------------------------------------------- | --------------- | ------ | ----- | -| `new_transaction_type/test/signature/invalid/r/0` | `0`. | | | -| `new_transaction_type/test/signature/invalid/r/secp256k1n_minus_one` | `SECP256K1N-1`. | | | -| `new_transaction_type/test/signature/invalid/r/secp256k1n` | `SECP256K1N`. | | | -| `new_transaction_type/test/signature/invalid/r/secp256k1n_plus_one` | `SECP256K1N+1`. | | | -| `new_transaction_type/test/signature/invalid/r/max_minus_one` | `2**256-1`. | | | -| `new_transaction_type/test/signature/invalid/r/max` | `2**256`. | | | +| `transaction_type/test/signature/invalid/r/0` | `0`. | | | +| `transaction_type/test/signature/invalid/r/secp256k1n_minus_one` | `SECP256K1N-1`. | | | +| `transaction_type/test/signature/invalid/r/secp256k1n` | `SECP256K1N`. | | | +| `transaction_type/test/signature/invalid/r/secp256k1n_plus_one` | `SECP256K1N+1`. | | | +| `transaction_type/test/signature/invalid/r/max_minus_one` | `2**256-1`. | | | +| `transaction_type/test/signature/invalid/r/max` | `2**256`. | | | ##### S | ID | Description | Status | Tests | | ------------------------------------------------------------------------- | -------------------------------------- | ------ | ----- | -| `new_transaction_type/test/signature/invalid/s/0` | `0`. | | | -| `new_transaction_type/test/signature/invalid/s/secp256k1n_half_minus_one` | `SECP256K1N//2-1`. | | | -| `new_transaction_type/test/signature/invalid/s/secp256k1n_half` | `SECP256K1N//2`. | | | -| `new_transaction_type/test/signature/invalid/s/secp256k1n_half_plus_one` | `SECP256K1N//2+1`. | | | -| `new_transaction_type/test/signature/invalid/s/secp256k1n_minus_one` | `SECP256K1N-1`. | | | -| `new_transaction_type/test/signature/invalid/s/secp256k1n` | `SECP256K1N`. | | | -| `new_transaction_type/test/signature/invalid/s/secp256k1n_plus_one` | `SECP256K1N+1`. | | | -| `new_transaction_type/test/signature/invalid/s/max_minus_one` | `2**256-1`. | | | -| `new_transaction_type/test/signature/invalid/s/max` | `2**256`. | | | -| `new_transaction_type/test/signature/invalid/s/complement` | `SECP256K1N - S` of a valid signature. | | | +| `transaction_type/test/signature/invalid/s/0` | `0`. | | | +| `transaction_type/test/signature/invalid/s/secp256k1n_half_minus_one` | `SECP256K1N//2-1`. | | | +| `transaction_type/test/signature/invalid/s/secp256k1n_half` | `SECP256K1N//2`. | | | +| `transaction_type/test/signature/invalid/s/secp256k1n_half_plus_one` | `SECP256K1N//2+1`. | | | +| `transaction_type/test/signature/invalid/s/secp256k1n_minus_one` | `SECP256K1N-1`. | | | +| `transaction_type/test/signature/invalid/s/secp256k1n` | `SECP256K1N`. | | | +| `transaction_type/test/signature/invalid/s/secp256k1n_plus_one` | `SECP256K1N+1`. | | | +| `transaction_type/test/signature/invalid/s/max_minus_one` | `2**256-1`. | | | +| `transaction_type/test/signature/invalid/s/max` | `2**256`. | | | +| `transaction_type/test/signature/invalid/s/complement` | `SECP256K1N - S` of a valid signature. | | | #### Transaction Attributes Readable From EVM | ID | Description | Status | Tests | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/tx_scoped_attributes/read` | Verify attributes that can be read in the EVM from transaction fields. | | | -| `new_transaction_type/test/tx_scoped_attributes/older_tx_types` | Verify attributes specific to the new transaction type that can be read in the EVM behave correctly on older transaction types. | | | +| `transaction_type/test/tx_scoped_attributes/read` | Verify attributes that can be read in the EVM from transaction fields. | | | +| `transaction_type/test/tx_scoped_attributes/older_tx_types` | Verify attributes specific to the new transaction type that can be read in the EVM behave correctly on older transaction types. | | | #### Transaction-Scoped Persistent Values Verify values or variables that are persistent through the execution of the transaction (e.g. transient storage, warm/cold accounts). -| `new_transaction_type/test/tx_scoped_attributes/persistent/throughout` | Persist throughout the entire transaction. | | | -| `new_transaction_type/test/tx_scoped_attributes/persistent/reset` | Reset on subsequent transactions in the same block. | | | +| `transaction_type/test/tx_scoped_attributes/persistent/throughout` | Persist throughout the entire transaction. | | | +| `transaction_type/test/tx_scoped_attributes/persistent/reset` | Reset on subsequent transactions in the same block. | | | #### Encoding (RLP, SSZ) @@ -879,8 +879,8 @@ Verify all listed scenarios for each transaction field. | ID | Description | Status | Tests | | ------------------------------------------------------------- | ------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/encoding/field_sizes/leading_zero` | Add leading zero byte. | | | -| `new_transaction_type/test/encoding/field_sizes/remove_byte` | Remove single byte from fixed-byte-length fields. | | | +| `transaction_type/test/encoding/field_sizes/leading_zero` | Add leading zero byte. | | | +| `transaction_type/test/encoding/field_sizes/remove_byte` | Remove single byte from fixed-byte-length fields. | | | ##### Fields of List Type @@ -888,23 +888,23 @@ Verify for each transaction field that is of type list. | ID | Description | Status | Tests | | ------------------------------------------------------------ | --------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/encoding/list_field/zero` | Zero-element list (Failure depending on EIP). | | | -| `new_transaction_type/test/encoding/list_field/max` | Max count list. | | | -| `new_transaction_type/test/encoding/list_field/max_plus_one` | Max count plus one list. | | | +| `transaction_type/test/encoding/list_field/zero` | Zero-element list (Failure depending on EIP). | | | +| `transaction_type/test/encoding/list_field/max` | Max count list. | | | +| `transaction_type/test/encoding/list_field/max_plus_one` | Max count plus one list. | | | ##### Extra/Missing Fields | ID | Description | Status | Tests | | --------------------------------------------------- | --------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/encoding/missing_fields` | Any fields particular to the new transaction types are missing. | | | -| `new_transaction_type/test/encoding/extra_fields` | Transaction contains extra fields. | | | +| `transaction_type/test/encoding/missing_fields` | Any fields particular to the new transaction types are missing. | | | +| `transaction_type/test/encoding/extra_fields` | Transaction contains extra fields. | | | ##### Serialization Corruption | ID | Description | Status | Tests | | ------------------------------------------------ | ------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/encoding/truncated` | Serialized bytes object is truncated by one byte. | | | -| `new_transaction_type/test/encoding/extra_bytes` | Serialized bytes object has one extra byte. | | | +| `transaction_type/test/encoding/truncated` | Serialized bytes object is truncated by one byte. | | | +| `transaction_type/test/encoding/extra_bytes` | Serialized bytes object has one extra byte. | | | ##### Serializable Fields @@ -912,7 +912,7 @@ Verify for each serializable field, all previous tests plus following listed sce | ID | Description | Status | Tests | | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------ | ----- | -| `new_transaction_type/test/encoding/new_types/incorrect_encoding` | Serializable field is encoded as bytes instead of using the correct encoding (e.g. list in the case of RLP). | | | +| `transaction_type/test/encoding/new_types/incorrect_encoding` | Serializable field is encoded as bytes instead of using the correct encoding (e.g. list in the case of RLP). | | | #### Out-of-bounds checks @@ -920,8 +920,8 @@ Verify if the transaction has out-of-bounds conditions in its fields and verify. | ID | Description | Status | Tests | | ------------------------------------------------------ | ----------------------------- | ------ | ----- | -| `new_transaction_type/test/out_of_bounds/max` | Max value for each field. | | | -| `new_transaction_type/test/out_of_bounds/max_plus_one` | Max value + 1 for each field. | | | +| `transaction_type/test/out_of_bounds/max` | Max value for each field. | | | +| `transaction_type/test/out_of_bounds/max_plus_one` | Max value + 1 for each field. | | | #### Contract creation @@ -929,14 +929,14 @@ Verify that the transaction can create new contracts if the transaction type sup | ID | Description | Status | Tests | | --------------------------------------------- | -------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/contract_creation` | Create contracts using new transaction type. | | | +| `transaction_type/test/contract_creation` | Create contracts using new transaction type. | | | #### Sender account modifications | ID | Description | Status | Tests | | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/sender_account/nonce` | Sender account has its nonce incremented at least by one after the transaction is included in a block (or more if the transaction type introduces a new mechanism that bumps the nonce by more than one). | | | -| `new_transaction_type/test/sender_account/balance` | Sender account has its balance reduced by the correct amount (gas consumed and value) at the start of execution (e.g. using `BALANCE`). | | | +| `transaction_type/test/sender_account/nonce` | Sender account has its nonce incremented at least by one after the transaction is included in a block (or more if the transaction type introduces a new mechanism that bumps the nonce by more than one). | | | +| `transaction_type/test/sender_account/balance` | Sender account has its balance reduced by the correct amount (gas consumed and value) at the start of execution (e.g. using `BALANCE`). | | | #### Block Level Interactions @@ -946,8 +946,8 @@ Verify a block where the new transaction type is the sole transaction contained | ID | Description | Status | Tests | | ---------------------------------------------------------------- | ------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/block_interactions/single_tx/invalid` | Invalid if `tx.gas_limit == block.gas_limit + 1`. | | | -| `new_transaction_type/test/block_interactions/single_tx/valid` | Valid if `tx.gas_limit == block.gas_limit`. | | | +| `transaction_type/test/block_interactions/single_tx/invalid` | Invalid if `tx.gas_limit == block.gas_limit + 1`. | | | +| `transaction_type/test/block_interactions/single_tx/valid` | Valid if `tx.gas_limit == block.gas_limit`. | | | ##### Two Transactions In Block @@ -955,8 +955,8 @@ Verify a block where the new transaction type is the last transaction contained | ID | Description | Status | Tests | | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/block_interactions/last_tx/valid` | Valid if `block.txs[0].gas_used + block.txs[1].gas_limit == block.gas_limit`. | | | -| `new_transaction_type/test/block_interactions/last_tx/invalid` | Invalid if `(block.txs[0].gas_used + block.txs[1].gas_limit == block.gas_limit + 1) and (block.txs[0].gas_used < block.gas_limit)`. | | | +| `transaction_type/test/block_interactions/last_tx/valid` | Valid if `block.txs[0].gas_used + block.txs[1].gas_limit == block.gas_limit`. | | | +| `transaction_type/test/block_interactions/last_tx/invalid` | Invalid if `(block.txs[0].gas_used + block.txs[1].gas_limit == block.gas_limit + 1) and (block.txs[0].gas_used < block.gas_limit)`. | | | ##### EIP-7825 @@ -964,8 +964,8 @@ Verify a transaction of the new type is rejected if its gas limit exceeds the [E | ID | Description | Status | Tests | | -------------------------------------------------------------- | -------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/block_interactions/eip7825/invalid` | Exceeds EIP-7825 gas limit by one. | | | -| `new_transaction_type/test/block_interactions/eip7825/valid` | Gas limit is exactly the EIP-7825 gas limit. | | | +| `transaction_type/test/block_interactions/eip7825/invalid` | Exceeds EIP-7825 gas limit by one. | | | +| `transaction_type/test/block_interactions/eip7825/valid` | Gas limit is exactly the EIP-7825 gas limit. | | | ##### Mixed transactions @@ -973,7 +973,7 @@ Verify a block with all transactions types including the new type is executed co | ID | Description | Status | Tests | | -------------------------------------------------------- | ------------------- | ------ | ----- | -| `new_transaction_type/test/block_interactions/mixed_txs` | Mixed transactions. | | | +| `transaction_type/test/block_interactions/mixed_txs` | Mixed transactions. | | | #### Fork transition @@ -981,12 +981,12 @@ Verify that a block prior to fork activation where the new transaction type is i | ID | Description | Status | Tests | | -------------------------------------------------- | ----------------------------------------------------------- | ------ | ----- | -| `new_transaction_type/test/fork_transition/before` | New transaction type included before fork activation block. | | | +| `transaction_type/test/fork_transition/before` | New transaction type included before fork activation block. | | | #### RPC Tests - \*Verify `eth_estimateGas` behavior for different valid combinations of the new transaction type. -- `new_transaction_type/test/rpc/send_raw` | Verify `eth_sendRawTransaction` using `execute`. +- `transaction_type/test/rpc/send_raw` | Verify `eth_sendRawTransaction` using `execute`. \*Tests must be added to [`execution-apis`](https://github.com/ethereum/execution-apis) repository. @@ -1005,7 +1005,7 @@ Verify, if possible, that the value can be set at genesis if the network startin | ID | Description | Status | Tests | | ------------------------------------- | ---------------------------------- | ------ | ----- | -| `new_block_header_field/test/genesis` | New block header field at genesis. | | | +| `block_header_field/test/genesis` | New block header field at genesis. | | | #### Value behavior @@ -1013,16 +1013,16 @@ Verify, given multiple initial values, that a block is accepted or rejected depe | ID | Description | Status | Tests | | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | ----- | -| `new_block_header_field/test/value_behavior/accept` | Block is accepted if the value is the correct expected for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | -| `new_block_header_field/test/value_behavior/reject` | Block is rejected if the value is modified (using `block.rlp_modifier`) to an incorrect value for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | +| `block_header_field/test/value_behavior/accept` | Block is accepted if the value is the correct expected for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | +| `block_header_field/test/value_behavior/reject` | Block is rejected if the value is modified (using `block.rlp_modifier`) to an incorrect value for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | #### Fork transition | ID | Description | Status | Tests | | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_block_header_field/test/fork_transition/initial` | Verify initial value of the field at the first block of the activation fork. | | | -| `new_block_header_field/test/fork_transition/before` | Verify that a block containing the new header field before the activation of the fork is invalid. | | | -| `new_block_header_field/test/fork_transition/after` | Verify that a block lacking the new header field at the activation of the fork is invalid. | | | +| `block_header_field/test/fork_transition/initial` | Verify initial value of the field at the first block of the activation fork. | | | +| `block_header_field/test/fork_transition/before` | Verify that a block containing the new header field before the activation of the fork is invalid. | | | +| `block_header_field/test/fork_transition/after` | Verify that a block lacking the new header field at the activation of the fork is invalid. | | | ### Framework Changes @@ -1042,15 +1042,15 @@ Verify, given multiple initial values, that a block is accepted or rejected depe | ID | Description | Status | Tests | | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_block_body_field/test/value_behavior/accept` | Block is accepted if the value is the correct expected for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | -| `new_block_body_field/test/value_behavior/reject` | Block is rejected if the value is modified (using appropriate `block`) to an incorrect value for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | +| `block_body_field/test/value_behavior/accept` | Block is accepted if the value is the correct expected for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | +| `block_body_field/test/value_behavior/reject` | Block is rejected if the value is modified (using appropriate `block`) to an incorrect value for the current block, depending on the circumstances that affect the value as defined in the EIP. | | | #### Fork transition | ID | Description | Status | Tests | | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_block_body_field/test/fork_transition/before` | Verify that a block containing the new block body field before the activation of the fork is invalid. | | | -| `new_block_body_field/test/fork_transition/after` | Verify that a block lacking the new block field at the activation of the fork is invalid. | | | +| `block_body_field/test/fork_transition/before` | Verify that a block containing the new block body field before the activation of the fork is invalid. | | | +| `block_body_field/test/fork_transition/after` | Verify that a block lacking the new block field at the activation of the fork is invalid. | | | ### Framework Changes @@ -1160,7 +1160,7 @@ Verify tests in `tests/cancun/eip4844_blobs` were correctly and automatically up | ID | Description | Status | Tests | | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | ------ | ----- | -| `new_execution_layer_request/test/cross_request_type/update` | Update `tests/prague/eip7685_general_purpose_el_requests` tests to include the new request type in the tests combinations. | | | +| `execution_layer_request/test/cross_request_type/update` | Update `tests/prague/eip7685_general_purpose_el_requests` tests to include the new request type in the tests combinations. | | | ### Framework Changes diff --git a/docs/writing_tests/eip_checklist.md b/docs/writing_tests/eip_checklist.md index 888af3465bd..26b722490e1 100644 --- a/docs/writing_tests/eip_checklist.md +++ b/docs/writing_tests/eip_checklist.md @@ -6,30 +6,44 @@ The EIP checklist feature helps track test coverage for EIP implementations by a When implementing tests for an EIP, you can mark specific tests as covering checklist items from the [EIP testing checklist template](../writing_tests/checklist_templates/eip_testing_checklist_template.md). The framework will then generate a filled checklist showing which items have been implemented. -## Using the `pytest.mark.eip_checklist` Marker +## Marking Tests as implementing EIP Checklist Items -To mark a test as implementing a specific checklist item: +To mark a test as implementing a specific checklist item, use the structured `EIPChecklist` class: + +### The `EIPChecklist` Class ```python import pytest from ethereum_test_tools import StateTestFiller +from ethereum_test_checklists import EIPChecklist -@pytest.mark.eip_checklist("new_transaction_type/test/intrinsic_validity/gas_limit/exact") +@EIPChecklist.TransactionType.Test.IntrinsicValidity.GasLimit.Exact() def test_exact_intrinsic_gas(state_test: StateTestFiller): """Test transaction with exact intrinsic gas limit.""" # Test implementation pass + +# You can also use the marker without parentheses +@EIPChecklist.TransactionType.Test.IntrinsicValidity.GasLimit.Insufficient +def test_insufficient_intrinsic_gas(state_test: StateTestFiller): + """Test transaction with insufficient intrinsic gas limit.""" + # Test implementation + pass ``` +The `EIPChecklist` class provides type safety and IDE autocompletion, making it easier to find and reference checklist items correctly. + ### Marker Parameters -- **First positional parameter** (required): The checklist item ID from the template +- **First positional parameter** (required): The checklist item ID (`EIPChecklist` reference) - **`eip` keyword parameter** (optional): List of additional EIPs covered by the test Example with multiple EIPs covered by the same test: ```python -@pytest.mark.eip_checklist("new_transaction_type/test/signature/invalid/v/0", eip=[7702, 2930]) +@EIPChecklist.TransactionType.Test.Signature.Invalid.V.Two( + eip=[7702, 2930] +) def test_invalid_signature(state_test: StateTestFiller): """Test invalid signature that affects multiple EIPs.""" pass @@ -40,8 +54,7 @@ def test_invalid_signature(state_test: StateTestFiller): You can use partial IDs that will match all checklist items starting with that prefix: ```python -# This will mark all items under "new_transaction_type/test/signature/invalid/" as covered -@pytest.mark.eip_checklist("new_transaction_type/test/signature/invalid/") +@EIPChecklist.TransactionType.Test.Signature.Invalid() def test_all_invalid_signatures(state_test: StateTestFiller): """Test covering all invalid signature scenarios.""" pass @@ -91,17 +104,44 @@ For checklist items that are not applicable to a specific EIP, create a file nam ```text # tests/prague/eip7702_set_code_tx/eip_checklist_not_applicable.txt -new_system_contract = EIP-7702 does not introduce a system contract -new_precompile = EIP-7702 does not introduce a precompile +system_contract = EIP-7702 does not introduce a system contract +precompile = EIP-7702 does not introduce a precompile ``` Format: `checklist_item_id = reason` Both files support partial ID matching, so you can mark entire sections as not applicable: +## MyPy Type Checking Support + +The `EIPChecklist` classes are made callable through a companion `.pyi` stub file that provides proper type hints for mypy. This allows you to use both decorator patterns without type checking errors: + +```python +# Both of these work with proper mypy support +@EIPChecklist.Opcode.Test.StackComplexOperations() # With parentheses +@EIPChecklist.Opcode.Test.StackComplexOperations # Without parentheses +``` + +### Regenerating Type Stubs + +If you modify the `EIPChecklist` class structure in `src/ethereum_test_checklists/eip_checklist.py`, you need to regenerate the type stub file: + +```bash +# Generate the stub file (for maintainers): +uv run generate_checklist_stubs + +# Preview what would be generated without writing the file +uv run generate_checklist_stubs --dry-run + +# Generate to a custom location +uv run generate_checklist_stubs --output path/to/custom/stubs.pyi +``` + +The generated stub file (`eip_checklist.pyi`) should be committed to the repository to ensure proper type checking for all developers. + ```text # Mark all system contract items as not applicable -new_system_contract/ = EIP does not introduce system contracts +system_contract/ = EIP does not introduce system contracts ``` ## Output Format @@ -135,28 +175,30 @@ Example output snippet: | `general/code_coverage/eels` | Run produced tests against EELS... | โœ… | Covered by EELS test suite | | `general/code_coverage/test_coverage` | Run coverage on the test code itself... | โœ… | `tests/prague/eip7702_set_code_tx/test_set_code_txs.py::test_set_code_txs` | -## New Transaction Type +## Transaction Type | ID | Description | Status | Tests | | -- | ----------- | ------ | ----- | -| `new_transaction_type/test/intrinsic_validity/gas_limit/exact` | Provide the exact intrinsic gas... | โœ… | `tests/prague/eip7702_set_code_tx/test_checklist_example.py::test_exact_intrinsic_gas` | -| `new_transaction_type/test/intrinsic_validity/gas_limit/insufficient` | Provide the exact intrinsic gas minus one... | | | +| `transaction_type/test/intrinsic_validity/gas_limit/exact` | Provide the exact intrinsic gas... | โœ… | `tests/prague/eip7702_set_code_tx/test_checklist_example.py::test_exact_intrinsic_gas` | +| `transaction_type/test/intrinsic_validity/gas_limit/insufficient` | Provide the exact intrinsic gas minus one... | | | -## New System Contract +## System Contract | ID | Description | Status | Tests | | -- | ----------- | ------ | ----- | -| `new_system_contract/test/deployment/missing` | Verify block execution behavior... | N/A | EIP-7702 does not introduce a system contract | +| `system_contract/test/deployment/missing` | Verify block execution behavior... | N/A | EIP-7702 does not introduce a system contract | ``` ## Best Practices 1. **Start with the checklist**: Review the checklist template before writing tests to ensure comprehensive coverage -2. **Use descriptive test names**: The test name will appear in the checklist, so make it clear what the test covers -3. **Mark items as you go**: Add `eip_checklist` markers while writing tests, not as an afterthought -4. **Document external coverage**: If items are covered by external tools/tests, document this in `eip_checklist_external_coverage.txt` -5. **Be explicit about N/A items**: Document why items are not applicable in `eip_checklist_not_applicable.txt` -6. **Use partial IDs wisely**: When a test covers multiple related items, use partial IDs to mark them all +2. **Use the `EIPChecklist` class**: Use `EIPChecklist.Opcode.Test.GasUsage.Normal` for type safety and IDE autocompletion +3. **Use descriptive test names**: The test name will appear in the checklist, so make it clear what the test covers +4. **Mark items as you go**: Add `eip_checklist` markers while writing tests, not as an afterthought +5. **Document external coverage**: If items are covered by external tools/tests, document this in `eip_checklist_external_coverage.txt` +6. **Be explicit about N/A items**: Document why items are not applicable in `eip_checklist_not_applicable.txt` +7. **Use partial IDs wisely**: When a test covers multiple related items, use partial IDs to mark them all +8. **Verify IDs before using**: Use `str(EIPChecklist.Section.Subsection)` to verify the exact string ID when needed ## Workflow Example @@ -174,7 +216,9 @@ Example output snippet: 2. **Mark tests as you implement them**: ```python - @pytest.mark.eip_checklist("new_opcode/test/gas_usage/normal") + from ethereum_test_checklists import EIPChecklist + + @EIPChecklist.Opcode.Test.GasUsage.Normal() def test_opcode_gas_consumption(state_test: StateTestFiller): """Test normal gas consumption of the new opcode.""" pass @@ -187,11 +231,23 @@ Example output snippet: general/code_coverage/eels = Covered by ethereum/execution-specs PR #1234 ``` + You can verify the correct ID using: + + ```python + # str(EIPChecklist.General.CodeCoverage.Eels) = "general/code_coverage/eels" + ``` + 4. **Mark non-applicable items**: ```text # eip_checklist_not_applicable.txt - new_precompile/ = EIP-9999 introduces an opcode, not a precompile + precompile/ = EIP-9999 introduces an opcode, not a precompile + ``` + + You can verify the correct ID using: + + ```python + # str(EIPChecklist.Precompile) = "precompile" ``` 5. **Generate and review checklist**: diff --git a/docs/writing_tests/exception_tests.md b/docs/writing_tests/exception_tests.md index b7f2eddfd32..af5d65aabe6 100644 --- a/docs/writing_tests/exception_tests.md +++ b/docs/writing_tests/exception_tests.md @@ -6,11 +6,11 @@ Exception tests are a special type of test which verify that an invalid transact To test for an exception, the test can use either of the following types from `ethereum_test_exceptions` library: -1. [`TransactionException`](../running_tests/test_formats/exceptions.md#transactionexception): To be added to the `error` field of the `Transaction` object, and to the `exception` field of the `Block` object that includes the transaction; this exception type is used when a transaction is invalid, and therefore when included in a block, the block is expected to be invalid too. This is different from valid transactions where an exception during EVM execution is expected (e.g. a revert, or out-of-gas), which can be included in valid blocks. +1. [`TransactionException`](../library/ethereum_test_exceptions.md#ethereum_test_exceptions.TransactionException): To be added to the `error` field of the `Transaction` object, and to the `exception` field of the `Block` object that includes the transaction; this exception type is used when a transaction is invalid, and therefore when included in a block, the block is expected to be invalid too. This is different from valid transactions where an exception during EVM execution is expected (e.g. a revert, or out-of-gas), which can be included in valid blocks. For an example, see [`eip3860_initcode.test_initcode.test_contract_creating_tx`](../tests/shanghai/eip3860_initcode/test_initcode/test_contract_creating_tx.md) which raises `TransactionException.INITCODE_SIZE_EXCEEDED` in the case that the initcode size exceeds the maximum allowed size. -2. [`BlockException`](../running_tests/test_formats/exceptions.md#blockexception): To be added to the `exception` field of the `Block` object; this exception type is used when a block is expected to be invalid, but the exception is related to a block property, e.g. an invalid value of the block header. +2. [`BlockException`](../library/ethereum_test_exceptions.md#ethereum_test_exceptions.BlockException): To be added to the `exception` field of the `Block` object; this exception type is used when a block is expected to be invalid, but the exception is related to a block property, e.g. an invalid value of the block header. For an example, see [`eip4844_blobs.test_excess_blob_gas.test_invalid_static_excess_blob_gas`](../tests/cancun/eip4844_blobs/test_excess_blob_gas/test_invalid_static_excess_blob_gas.md) which raises `BlockException.INCORRECT_EXCESS_BLOB_GAS` in the case that the `excessBlobGas` remains unchanged but the parent blobs included are not `TARGET_BLOBS_PER_BLOCK`. @@ -19,7 +19,7 @@ Although exceptions can be combined with the `|` operator to indicate that a tes ## Adding a new exception -If a test requires a new exception, because none of the existing ones is suitable for the test, a new exception can be added to either [`TransactionException`](../running_tests/test_formats/exceptions.md#transactionexception) or [`BlockException`](../running_tests/test_formats/exceptions.md#blockexception) classes. +If a test requires a new exception, because none of the existing ones is suitable for the test, a new exception can be added to either [`TransactionException`](../library/ethereum_test_exceptions.md#ethereum_test_exceptions.TransactionException) or [`BlockException`](../library/ethereum_test_exceptions.md#ethereum_test_exceptions.BlockException) classes. The new exception should be added as a new enum value, and the docstring of the attribute should be a string that describes the exception. diff --git a/pyproject.toml b/pyproject.toml index 9b04f505b49..1453da7315a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,6 +91,7 @@ check_eip_versions = "cli.pytest_commands.check_eip_versions:check_eip_versions" consume = "cli.pytest_commands.consume:consume" protec = "cli.pytest_commands.consume:consume" checklist = "cli.pytest_commands.checklist:checklist" +generate_checklist_stubs = "cli.generate_checklist_stubs:generate_checklist_stubs" genindex = "cli.gen_index:generate_fixtures_index_cli" gentest = "cli.gentest:generate" eofwrap = "cli.eofwrap:eof_wrap" diff --git a/src/cli/generate_checklist_stubs.py b/src/cli/generate_checklist_stubs.py new file mode 100644 index 00000000000..36d3839b369 --- /dev/null +++ b/src/cli/generate_checklist_stubs.py @@ -0,0 +1,178 @@ +"""CLI tool to generate mypy stub files for EIPChecklist classes.""" + +import sys +from pathlib import Path + +import click + + +def has_nested_classes(obj) -> bool: + """Check if an object has nested classes with _path attribute.""" + for attr_name in dir(obj): + if attr_name.startswith("_"): + continue + attr = getattr(obj, attr_name) + if isinstance(attr, type) and hasattr(attr, "_path"): + return True + return False + + +def generate_class_stub(obj, class_name: str, indent: int = 0) -> list[str]: + """Generate stub for a class and its nested classes.""" + lines = [] + spaces = " " * indent + + # Get all attributes that are classes with _path + nested_classes = [] + leaf_classes = [] + + for attr_name in dir(obj): + if attr_name.startswith("_"): + continue + + attr = getattr(obj, attr_name) + if isinstance(attr, type) and hasattr(attr, "_path"): + if has_nested_classes(attr): + nested_classes.append((attr_name, attr)) + else: + leaf_classes.append(attr_name) + + # Determine if this class itself should be callable + is_callable = class_name != "EIPChecklist" # All classes except the root are callable + + # Generate class declaration + if is_callable: + lines.append(f"{spaces}class {class_name}(_CallableChecklistItem):") + else: + lines.append(f"{spaces}class {class_name}:") + + # If no nested content, add pass + if not nested_classes and not leaf_classes: + lines.append(f"{spaces} pass") + return lines + + # Generate leaf classes (final callable items) + for attr_name in sorted(leaf_classes): + lines.append(f"{spaces} {attr_name}: _CallableChecklistItem") + + # Add blank line if we have both leaf classes and nested classes + if leaf_classes and nested_classes: + lines.append("") + + # Generate nested classes + for i, (attr_name, attr_obj) in enumerate(sorted(nested_classes)): + if i > 0: # Add blank line between nested classes + lines.append("") + nested_lines = generate_class_stub(attr_obj, attr_name, indent + 1) + lines.extend(nested_lines) + + return lines + + +@click.command() +@click.option( + "--output", + "-o", + type=click.Path(), + help="Output path for the stub file (default: auto-detect)", +) +@click.option( + "--dry-run", + is_flag=True, + help="Print the generated stub content instead of writing to file", +) +def generate_checklist_stubs(output: str | None, dry_run: bool) -> None: + """ + Generate mypy stub files for EIPChecklist classes. + + This is a development tool that generates .pyi stub files to help mypy + understand that EIPChecklist classes are callable, fixing type checking issues. + + Examples: + # Generate stub files (auto-detect location) + uv run generate_checklist_stubs + + # Generate to specific location + uv run generate_checklist_stubs --output /path/to/stubs.pyi + + # Preview content without writing + uv run generate_checklist_stubs --dry-run + + """ + try: + # Add src to path so we can import the module + src_path = Path(__file__).parent.parent + sys.path.insert(0, str(src_path)) + + from ethereum_test_checklists.eip_checklist import EIPChecklist + + stub_content = '''""" +Type stubs for EIP checklist - auto-generated. + +DO NOT EDIT MANUALLY - This file is generated by `uv run generate_checklist_stubs` +""" + +from typing import Any, Callable, TypeVar, overload + +import pytest + +F = TypeVar("F", bound=Callable[..., Any]) + +class _CallableChecklistItem: + """Base type for all callable checklist items.""" + + @overload + def __call__(self, func: F) -> F: ... + @overload + def __call__(self, *, eip: Any = ..., **kwargs: Any) -> pytest.MarkDecorator: ... + def __str__(self) -> str: ... + +''' + + # Generate the main EIPChecklist structure + lines = generate_class_stub(EIPChecklist, "EIPChecklist", indent=0) + stub_content += "\n".join(lines) + "\n" + + if dry_run: + click.echo("Generated stub content:") + click.echo("=" * 50) + click.echo(stub_content) + return + + # Determine output path + if output: + stub_path = Path(output) + else: + stub_path = src_path / "ethereum_test_checklists" / "eip_checklist.pyi" + + # Write to the stub file + stub_path.parent.mkdir(parents=True, exist_ok=True) + stub_path.write_text(stub_content) + + click.echo(f"โœ… Generated stub file: {stub_path}") + click.echo(f"๐Ÿ“Š Total lines: {len(stub_content.splitlines())}") + + # Count classes for verification + class_count = stub_content.count("class ") + callable_count = stub_content.count(": _CallableChecklistItem") + click.echo(f"๐Ÿ—๏ธ Classes: {class_count}, Callable items: {callable_count}") + + click.echo( + "\n๐Ÿ’ก This stub file helps mypy understand that EIPChecklist classes are callable." + ) + click.echo( + " You can now use @EIPChecklist.Opcode.Test.StackComplexOperations() " + "without type errors!" + ) + + except ImportError as e: + click.echo(f"โŒ Error importing EIPChecklist: {e}", err=True) + click.echo("๐Ÿ’ก Make sure you're running this from the project root", err=True) + sys.exit(1) + except Exception as e: + click.echo(f"โŒ Error generating stubs: {e}", err=True) + sys.exit(1) + + +if __name__ == "__main__": + generate_checklist_stubs() diff --git a/src/ethereum_test_checklists/__init__.py b/src/ethereum_test_checklists/__init__.py new file mode 100644 index 00000000000..f12c6fea1f1 --- /dev/null +++ b/src/ethereum_test_checklists/__init__.py @@ -0,0 +1,5 @@ +"""Ethereum test checklists module for EIP testing coverage tracking.""" + +from .eip_checklist import EIPChecklist + +__all__ = ["EIPChecklist"] diff --git a/src/ethereum_test_checklists/eip_checklist.py b/src/ethereum_test_checklists/eip_checklist.py new file mode 100644 index 00000000000..58b5379914b --- /dev/null +++ b/src/ethereum_test_checklists/eip_checklist.py @@ -0,0 +1,1677 @@ +""" +EIP Testing Checklist Enum definitions. + +Note: This module includes a companion .pyi stub file that provides mypy type hints +for making EIPChecklist classes callable. The stub file is auto-generated using: + uv run generate_checklist_stubs + +If you modify the EIPChecklist class structure, regenerate the stub file to maintain +proper type checking support. +""" + +import re + +import pytest + + +def camel_to_snake(name: str) -> str: + """Convert CamelCase to snake_case.""" + # Insert an underscore before any uppercase letter that follows a lowercase letter + s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name) + # Insert an underscore before any uppercase letter that follows a lowercase letter or number + return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower() + + +class ChecklistItemMeta(type): + """Metaclass for checklist items that provides string representation.""" + + _path: str = "" + _override_name: str = "" + + def __new__(mcs, name: str, bases: tuple, namespace: dict, **kwargs): + """Create a new class with the parent path set.""" + parent_path = kwargs.get("parent_path", "") + override_name = kwargs.get("override_name", None) + + # Create the class + cls = super().__new__(mcs, name, bases, namespace) + + cls._override_name = override_name + + # Set the path for this class + item_name = override_name if override_name is not None else camel_to_snake(name) + + if parent_path: + # Convert class name to snake_case and append to parent path + cls._path = f"{parent_path}/{item_name}" + else: + cls._path = item_name + + # Process nested classes + for attr_name, attr_value in namespace.items(): + if isinstance(attr_value, type) and not attr_name.startswith("_"): + # Create a new class with the parent path set + assert isinstance(attr_value, ChecklistItemMeta) + nested_cls = ChecklistItemMeta( + attr_value.__name__, + attr_value.__bases__, + dict(attr_value.__dict__), + parent_path=cls._path, + override_name=attr_value._override_name, + ) + setattr(cls, attr_name, nested_cls) + + return cls + + def __str__(cls) -> str: + """Return the path for this checklist item.""" + return cls._path + + def __repr__(cls) -> str: + """Return a representation of this checklist item.""" + return f"" + + def __call__(cls, *args, **kwargs): + """Return a pytest mark decorator for the checklist item.""" + # If called with a function as the first argument (direct decorator usage) + # and no other arguments, apply the decorator to the function + if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): + func = args[0] + marker = pytest.mark.eip_checklist(cls._path) + return marker(func) + # Otherwise, return a pytest mark decorator + return pytest.mark.eip_checklist(cls._path, *args, **kwargs) + + +class ChecklistItem(metaclass=ChecklistItemMeta): + """Base class for checklist items.""" + + pass + + +class EIPChecklist: + """ + Main namespace for EIP testing checklist items. + + This class provides a structured way to reference checklist items for EIP testing. + The class structure is automatically converted to callable pytest markers. + + Note: If you modify this class structure, regenerate the type stub file using: + uv run generate_checklist_stubs + + Examples: + @EIPChecklist.Opcode.Test.GasUsage.Normal() + def test_normal_gas(): + pass + + @EIPChecklist.Opcode.Test.StackOverflow + def test_stack_overflow(): + pass + + """ + + class General(ChecklistItem): + """General checklist items.""" + + class CodeCoverage(ChecklistItem): + """Code coverage checklist items.""" + + class Eels(ChecklistItem): + """EELS code coverage.""" + + pass + + class TestCoverage(ChecklistItem): + """Test code coverage.""" + + pass + + class SecondClient(ChecklistItem): + """Second client code coverage.""" + + pass + + class Opcode(ChecklistItem): + """New opcode checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new opcode.""" + + class MemExp(ChecklistItem): + """Memory expansion tests.""" + + class ZeroBytesZeroOffset(ChecklistItem): + """Zero bytes expansion with zero-offset.""" + + pass + + class ZeroBytesMaxOffset(ChecklistItem): + """Zero bytes expansion with 2**256-1 offset.""" + + pass + + class SingleByte(ChecklistItem): + """Single byte expansion.""" + + pass + + class ThirtyOneBytes(ChecklistItem, override_name="31_bytes"): + """31 bytes expansion.""" + + pass + + class ThirtyTwoBytes(ChecklistItem, override_name="32_bytes"): + """32 bytes expansion.""" + + pass + + class ThirtyThreeBytes(ChecklistItem, override_name="33_bytes"): + """33 bytes expansion.""" + + pass + + class SixtyFourBytes(ChecklistItem, override_name="64_bytes"): + """64 bytes expansion.""" + + pass + + class TwoThirtyTwoMinusOneBytes( + ChecklistItem, override_name="2_32_minus_one_bytes" + ): + """2**32-1 bytes expansion.""" + + pass + + class TwoThirtyTwoBytes(ChecklistItem, override_name="2_32_bytes"): + """2**32 bytes expansion.""" + + pass + + class TwoSixtyFourMinusOneBytes( + ChecklistItem, override_name="2_64_minus_one_bytes" + ): + """2**64-1 bytes expansion.""" + + pass + + class TwoSixtyFourBytes(ChecklistItem, override_name="2_64_bytes"): + """2**64 bytes expansion.""" + + pass + + class TwoTwoFiftySixMinusOneBytes( + ChecklistItem, override_name="2_256_minus_one_bytes" + ): + """2**256-1 bytes expansion.""" + + pass + + class StackOverflow(ChecklistItem): + """Stack overflow test.""" + + pass + + class StackUnderflow(ChecklistItem): + """Stack underflow test.""" + + pass + + class StackComplexOperations(ChecklistItem): + """Stack complex operations tests.""" + + class StackHeights(ChecklistItem): + """Stack height tests.""" + + class Zero(ChecklistItem): + """Operation on an empty stack.""" + + pass + + class Odd(ChecklistItem): + """Operation on a stack with odd height.""" + + pass + + class Even(ChecklistItem): + """Operation on a stack with even height.""" + + pass + + class DataPortionVariables(ChecklistItem, override_name="data_portion_variables"): + """ + If the opcode contains variables in its data portion, for each variable `n` + of the opcode that accesses the nth stack item, test `n` being. + """ + + class Top(ChecklistItem): + """`n` is the top stack item.""" + + pass + + class Bottom(ChecklistItem): + """`n` is the bottom stack item.""" + + pass + + class Middle(ChecklistItem): + """`n` is the middle stack item.""" + + pass + + class ExecutionContext(ChecklistItem): + """Execution context tests.""" + + class Call(ChecklistItem): + """CALL context.""" + + pass + + class Staticcall(ChecklistItem): + """STATICCALL context tests.""" + + class BanCheck(ChecklistItem): + """Ban check for state modifications.""" + + pass + + class BanNoModification(ChecklistItem): + """Ban even without modifications.""" + + pass + + class SubCalls(ChecklistItem): + """Sub-calls verification.""" + + pass + + class Delegatecall(ChecklistItem): + """DELEGATECALL context.""" + + pass + + class Storage(ChecklistItem): + """DELEGATECALL storage modification.""" + + pass + + class Balance(ChecklistItem): + """DELEGATECALL balance modification.""" + + pass + + class Code(ChecklistItem): + """DELEGATECALL code modification.""" + + pass + + class Callcode(ChecklistItem): + """CALLCODE context.""" + + pass + + class Initcode(ChecklistItem): + """Initcode execution tests.""" + + class Behavior(ChecklistItem): + """Initcode behavior.""" + + pass + + class Tx(ChecklistItem): + """Initcode from transaction.""" + + pass + + class Opcode(ChecklistItem): + """Initcode from opcode.""" + + pass + + class Reentry(ChecklistItem): + """Initcode re-entry.""" + + pass + + class SetCode(ChecklistItem): + """Set-code delegated account.""" + + pass + + class TxContext(ChecklistItem): + """Transaction context dependent.""" + + pass + + class BlockContext(ChecklistItem): + """Block context dependent.""" + + pass + + class ReturnData(ChecklistItem): + """Return data tests.""" + + class Buffer(ChecklistItem): + """Return buffer tests.""" + + class Current(ChecklistItem): + """Return buffer at current call context.""" + + pass + + class Parent(ChecklistItem): + """Return buffer at parent call context.""" + + pass + + class GasUsage(ChecklistItem): + """Gas usage tests.""" + + class Normal(ChecklistItem): + """Normal operation gas usage.""" + + pass + + class MemoryExpansion(ChecklistItem): + """Memory expansion gas usage.""" + + pass + + class OutOfGasExecution(ChecklistItem): + """Out-of-gas due to opcode inputs.""" + + pass + + class OutOfGasMemory(ChecklistItem): + """Out-of-gas due to memory expansion.""" + + pass + + class OrderOfOperations(ChecklistItem): + """Order of operations tests.""" + + class Exact(ChecklistItem): + """Exact gas required.""" + + pass + + class Oog(ChecklistItem): + """Out-of-gas with 1 gas difference.""" + + pass + + class Terminating(ChecklistItem): + """Terminating opcode tests.""" + + class Scenarios(ChecklistItem): + """Termination scenarios.""" + + class TopLevel(ChecklistItem): + """Top-level call termination.""" + + pass + + class SubLevel(ChecklistItem): + """Sub-level call termination.""" + + pass + + class Initcode(ChecklistItem): + """Initcode termination.""" + + pass + + class Rollback(ChecklistItem): + """Rollback tests.""" + + class Balance(ChecklistItem): + """Balance changes rollback.""" + + pass + + class Storage(ChecklistItem): + """Storage changes rollback.""" + + pass + + class Contracts(ChecklistItem): + """Contract creations rollback.""" + + pass + + class Nonce(ChecklistItem): + """Nonce increments rollback.""" + + pass + + class Logs(ChecklistItem): + """Log events rollback.""" + + pass + + class OutOfBounds(ChecklistItem): + """Out-of-bounds checks.""" + + class Verify(ChecklistItem): + """Verification tests.""" + + class Max(ChecklistItem): + """Max value for each parameter.""" + + pass + + class MaxPlusOne(ChecklistItem): + """Max value + 1 for each parameter.""" + + pass + + class ExceptionalAbort(ChecklistItem): + """Exceptional abort conditions.""" + + pass + + class DataPortion(ChecklistItem): + """Data portion tests.""" + + class AllZeros(ChecklistItem): + """All zeros data portion.""" + + pass + + class MaxValue(ChecklistItem): + """Max value data portion.""" + + pass + + class Jump(ChecklistItem): + """Jump into the data portion.""" + + pass + + class ContractCreation(ChecklistItem): + """Contract creation tests.""" + + class Address(ChecklistItem): + """Address calculation.""" + + pass + + class Failure(ChecklistItem): + """Creation failure tests.""" + + class Oog(ChecklistItem): + """Out-of-gas failure.""" + + pass + + class InsufficientValue(ChecklistItem): + """Insufficient value failure.""" + + pass + + class Collision(ChecklistItem): + """Address collision failure.""" + + pass + + class Recursive(ChecklistItem): + """Recursive contract creation.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Invalid(ChecklistItem): + """Invalid before/after fork.""" + + pass + + class At(ChecklistItem): + """Behavior at transition block.""" + + pass + + class Precompile(ChecklistItem): + """New precompile checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new precompile.""" + + class CallContexts(ChecklistItem): + """Call context tests.""" + + class Normal(ChecklistItem): + """CALL context.""" + + pass + + class Delegate(ChecklistItem): + """DELEGATECALL context.""" + + pass + + class Static(ChecklistItem): + """STATICCALL context.""" + + pass + + class Callcode(ChecklistItem): + """CALLCODE context.""" + + pass + + class TxEntry(ChecklistItem): + """Transaction entry-point.""" + + pass + + class Initcode(ChecklistItem): + """Initcode call tests.""" + + class CREATE(ChecklistItem, override_name="CREATE"): + """Call from CREATE/CREATE2 initcode.""" + + pass + + class Tx(ChecklistItem): + """Call from transaction initcode.""" + + pass + + class SetCode(ChecklistItem): + """Set-code delegated address.""" + + pass + + class Inputs(ChecklistItem): + """Input tests.""" + + class Valid(ChecklistItem): + """Valid inputs.""" + + class Boundary(ChecklistItem): + """Valid boundary values.""" + + pass + + class Crypto(ChecklistItem): + """Valid cryptographic inputs.""" + + pass + + class AllZeros(ChecklistItem): + """All zeros input.""" + + pass + + class MaxValues(ChecklistItem): + """Max values input.""" + + pass + + class Invalid(ChecklistItem): + """Invalid inputs.""" + + class Crypto(ChecklistItem): + """Invalid cryptographic inputs.""" + + pass + + class Corrupted(ChecklistItem): + """Corrupted inputs.""" + + pass + + class ValueTransfer(ChecklistItem): + """Value transfer tests.""" + + class Fee(ChecklistItem): + """Fee-based precompile tests.""" + + class Under(ChecklistItem): + """Under required fee.""" + + pass + + class Exact(ChecklistItem): + """Exact required fee.""" + + pass + + class Over(ChecklistItem): + """Over required fee.""" + + pass + + class NoFee(ChecklistItem): + """No-fee precompile.""" + + pass + + class OutOfBounds(ChecklistItem): + """Out-of-bounds checks.""" + + class Max(ChecklistItem): + """Max value for each input.""" + + pass + + class MaxPlusOne(ChecklistItem): + """Max value + 1 for each input.""" + + pass + + class InputLengths(ChecklistItem): + """Input length tests.""" + + class Zero(ChecklistItem): + """Zero-length calldata.""" + + pass + + class Static(ChecklistItem): + """Static input length tests.""" + + class Correct(ChecklistItem): + """Correct static-length calldata.""" + + pass + + class TooShort(ChecklistItem): + """Calldata too short.""" + + pass + + class TooLong(ChecklistItem): + """Calldata too long.""" + + pass + + class Dynamic(ChecklistItem): + """Dynamic input length tests.""" + + class Valid(ChecklistItem): + """Valid dynamic lengths.""" + + pass + + class TooShort(ChecklistItem): + """Calldata too short.""" + + pass + + class TooLong(ChecklistItem): + """Calldata too long.""" + + pass + + class GasUsage(ChecklistItem): + """Gas usage tests.""" + + class Constant(ChecklistItem): + """Constant gas cost tests.""" + + class Exact(ChecklistItem): + """Exact gas consumption.""" + + pass + + class Oog(ChecklistItem): + """Out-of-gas error.""" + + pass + + class Dynamic(ChecklistItem): + """Dynamic gas cost tests.""" + + class Exact(ChecklistItem): + """Exact gas consumption.""" + + pass + + class Oog(ChecklistItem): + """Out-of-gas error.""" + + pass + + class ExcessiveGasUsage(ChecklistItem): + """Excessive gas usage.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Before(ChecklistItem): + """Before fork activation tests.""" + + class InvalidInput(ChecklistItem): + """Invalid input call.""" + + pass + + class ZeroGas(ChecklistItem): + """Zero-gas call.""" + + pass + + class Cold(ChecklistItem): + """Cold precompile address.""" + + pass + + class After(ChecklistItem): + """After fork activation tests.""" + + class Warm(ChecklistItem): + """Warm precompile address.""" + + pass + + class RemovedPrecompile(ChecklistItem): + """Removed precompile checklist items.""" + + class Test(ChecklistItem): + """Test vectors for removed precompile.""" + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Operational(ChecklistItem): + """Precompile operation on fork activation.""" + + pass + + class Before(ChecklistItem): + """Before fork tests.""" + + class Warm(ChecklistItem): + """Warm precompile address.""" + + pass + + class After(ChecklistItem): + """After fork tests.""" + + class Cold(ChecklistItem): + """Cold precompile address.""" + + pass + + class SystemContract(ChecklistItem): + """New system contract checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new system contract.""" + + class CallContexts(ChecklistItem): + """Call context tests.""" + + class Normal(ChecklistItem): + """CALL context.""" + + pass + + class Delegate(ChecklistItem): + """DELEGATECALL context.""" + + pass + + class Static(ChecklistItem): + """STATICCALL context.""" + + pass + + class Callcode(ChecklistItem): + """CALLCODE context.""" + + pass + + class TxEntry(ChecklistItem): + """Transaction entry-point.""" + + pass + + class Initcode(ChecklistItem): + """Initcode call tests.""" + + class CREATE(ChecklistItem, override_name="CREATE"): + """Call from CREATE/CREATE2 initcode.""" + + pass + + class Tx(ChecklistItem): + """Call from transaction initcode.""" + + pass + + class SetCode(ChecklistItem): + """Set-code delegated address.""" + + pass + + class Inputs(ChecklistItem): + """Input tests.""" + + class Valid(ChecklistItem): + """Valid inputs.""" + + pass + + class Boundary(ChecklistItem): + """Boundary values.""" + + pass + + class AllZeros(ChecklistItem): + """All zeros input.""" + + pass + + class MaxValues(ChecklistItem): + """Max values input.""" + + pass + + class Invalid(ChecklistItem): + """Invalid inputs.""" + + class Checks(ChecklistItem): + """Invalid validity checks.""" + + pass + + class Crypto(ChecklistItem): + """Invalid cryptographic inputs.""" + + pass + + class Corrupted(ChecklistItem): + """Corrupted inputs.""" + + pass + + class ValueTransfer(ChecklistItem): + """Value transfer tests.""" + + class Fee(ChecklistItem): + """Fee-based system contract tests.""" + + class Under(ChecklistItem): + """Under required fee.""" + + pass + + class Exact(ChecklistItem): + """Exact required fee.""" + + pass + + class Over(ChecklistItem): + """Over required fee.""" + + pass + + class NoFee(ChecklistItem): + """No-fee system contract.""" + + pass + + class OutOfBounds(ChecklistItem): + """Out-of-bounds checks.""" + + class Max(ChecklistItem): + """Max value for each input.""" + + pass + + class MaxPlusOne(ChecklistItem): + """Max value + 1 for each input.""" + + pass + + class InputLengths(ChecklistItem): + """Input length tests.""" + + class Zero(ChecklistItem): + """Zero-length calldata.""" + + pass + + class Static(ChecklistItem): + """Static input length tests.""" + + class Correct(ChecklistItem): + """Correct static-length calldata.""" + + pass + + class TooShort(ChecklistItem): + """Calldata too short.""" + + pass + + class TooLong(ChecklistItem): + """Calldata too long.""" + + pass + + class Dynamic(ChecklistItem): + """Dynamic input length tests.""" + + class Valid(ChecklistItem): + """Valid dynamic lengths.""" + + pass + + class TooShort(ChecklistItem): + """Calldata too short.""" + + pass + + class TooLong(ChecklistItem): + """Calldata too long.""" + + pass + + class GasUsage(ChecklistItem): + """Gas usage tests.""" + + class Constant(ChecklistItem): + """Constant gas cost tests.""" + + class Exact(ChecklistItem): + """Exact gas consumption.""" + + pass + + class Oog(ChecklistItem): + """Out-of-gas error.""" + + pass + + class Dynamic(ChecklistItem): + """Dynamic gas cost tests.""" + + class Exact(ChecklistItem): + """Exact gas consumption.""" + + pass + + class Oog(ChecklistItem): + """Out-of-gas error.""" + + pass + + class ExcessiveGas(ChecklistItem): + """Excessive gas tests.""" + + class BlockGas(ChecklistItem): + """Exhaust block gas limit.""" + + pass + + class SystemCall(ChecklistItem): + """Excessive gas on system call.""" + + pass + + class Deployment(ChecklistItem): + """Deployment tests.""" + + class Missing(ChecklistItem): + """Missing system contract.""" + + pass + + class Address(ChecklistItem): + """Deployment address verification.""" + + pass + + class ContractVariations(ChecklistItem): + """Contract variation tests.""" + + class Networks(ChecklistItem): + """Different network variations.""" + + pass + + class ContractSubstitution(ChecklistItem): + """Contract substitution tests.""" + + class ReturnLengths(ChecklistItem): + """Modified return value lengths.""" + + pass + + class Logs(ChecklistItem): + """Modified logs.""" + + pass + + class RaisesException(ChecklistItem, override_name="exception"): + """Modified to cause exception.""" + + pass + + class GasLimitSuccess(ChecklistItem): + """30M gas consumption success.""" + + pass + + class GasLimitFailure(ChecklistItem): + """30M+1 gas consumption failure.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class CallBeforeFork(ChecklistItem): + """Call system contract before fork.""" + + pass + + class TransactionType(ChecklistItem): + """New transaction type checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new transaction type.""" + + class IntrinsicValidity(ChecklistItem): + """Intrinsic validity tests.""" + + class GasLimit(ChecklistItem): + """Gas limit tests.""" + + class Exact(ChecklistItem): + """Exact intrinsic gas.""" + + pass + + class Insufficient(ChecklistItem): + """Insufficient gas.""" + + pass + + class MaxFee(ChecklistItem): + """Max fee tests.""" + + class MaxPriorityLowerThanMaxFee(ChecklistItem): + """Max priority < max fee.""" + + pass + + class MaxPriorityEqualToMaxFee(ChecklistItem): + """Max priority == max fee.""" + + pass + + class BaseLower(ChecklistItem): + """Max fee < base fee.""" + + pass + + class BaseEqual(ChecklistItem): + """Max fee == base fee.""" + + pass + + class ChainId(ChecklistItem): + """Chain ID validation.""" + + pass + + class NonceMinusOne(ChecklistItem): + """Nonce == sender.nonce - 1.""" + + pass + + class NoncePlusOne(ChecklistItem): + """Nonce == sender.nonce + 1.""" + + pass + + class NonceExact(ChecklistItem): + """Nonce == sender.nonce.""" + + pass + + class To(ChecklistItem): + """To address validation.""" + + pass + + class ValueNonZeroInsufficientBalance(ChecklistItem): + """Non-zero value with insufficient balance.""" + + pass + + class ValueNonZeroSufficientBalance(ChecklistItem): + """Non-zero value with sufficient balance.""" + + pass + + class ValueZeroInsufficientBalance(ChecklistItem): + """Zero value with insufficient balance.""" + + pass + + class ValueZeroSufficientBalance(ChecklistItem): + """Zero value with sufficient balance.""" + + pass + + class DataFloorAboveIntrinsicGasCost(ChecklistItem): + """Data floor cost above intrinsic gas.""" + + pass + + class Signature(ChecklistItem): + """Signature tests.""" + + class Invalid(ChecklistItem): + """Invalid signature tests.""" + + class FieldOutsideCurve(ChecklistItem): + """Field outside curve.""" + + pass + + class V(ChecklistItem): + """Invalid V values.""" + + class Two(ChecklistItem, override_name="2"): + """V = 2.""" + + pass + + class TwentySeven(ChecklistItem, override_name="27"): + """V = 27.""" + + pass + + class TwentyEight(ChecklistItem, override_name="28"): + """V = 28.""" + + pass + + class ThirtyFive(ChecklistItem, override_name="35"): + """V = 35.""" + + pass + + class ThirtySix(ChecklistItem, override_name="36"): + """V = 36.""" + + pass + + class Max(ChecklistItem): + """V = 2**8-1.""" + + pass + + class R(ChecklistItem): + """Invalid R values.""" + + class Zero(ChecklistItem, override_name="0"): + """R = 0.""" + + pass + + class Secp256k1nMinusOne(ChecklistItem): + """R = SECP256K1N-1.""" + + pass + + class Secp256k1n(ChecklistItem): + """R = SECP256K1N.""" + + pass + + class Secp256k1nPlusOne(ChecklistItem): + """R = SECP256K1N+1.""" + + pass + + class MaxMinusOne(ChecklistItem): + """R = 2**256-1.""" + + pass + + class Max(ChecklistItem): + """R = 2**256.""" + + pass + + class S(ChecklistItem): + """Invalid S values.""" + + class Zero(ChecklistItem, override_name="0"): + """S = 0.""" + + pass + + class Secp256k1nHalfMinusOne(ChecklistItem): + """S = SECP256K1N//2-1.""" + + pass + + class Secp256k1nHalf(ChecklistItem): + """S = SECP256K1N//2.""" + + pass + + class Secp256k1nHalfPlusOne(ChecklistItem): + """S = SECP256K1N//2+1.""" + + pass + + class Secp256k1nMinusOne(ChecklistItem): + """S = SECP256K1N-1.""" + + pass + + class Secp256k1n(ChecklistItem): + """S = SECP256K1N.""" + + pass + + class Secp256k1nPlusOne(ChecklistItem): + """S = SECP256K1N+1.""" + + pass + + class MaxMinusOne(ChecklistItem): + """S = 2**256-1.""" + + pass + + class Max(ChecklistItem): + """S = 2**256.""" + + pass + + class Complement(ChecklistItem): + """S = SECP256K1N - S.""" + + pass + + class TxScopedAttributes(ChecklistItem): + """Transaction-scoped attributes.""" + + class Read(ChecklistItem): + """Read attributes from EVM.""" + + pass + + class OlderTxTypes(ChecklistItem): + """Attributes on older tx types.""" + + pass + + class Persistent(ChecklistItem): + """Persistent values.""" + + class Throughout(ChecklistItem): + """Persist throughout transaction.""" + + pass + + class Reset(ChecklistItem): + """Reset on subsequent transactions.""" + + pass + + class Encoding(ChecklistItem): + """Encoding tests.""" + + class FieldSizes(ChecklistItem): + """Field size tests.""" + + class LeadingZero(ChecklistItem): + """Add leading zero byte.""" + + pass + + class RemoveByte(ChecklistItem): + """Remove single byte.""" + + pass + + class ListField(ChecklistItem): + """List field tests.""" + + class Zero(ChecklistItem): + """Zero-element list.""" + + pass + + class Max(ChecklistItem): + """Max count list.""" + + pass + + class MaxPlusOne(ChecklistItem): + """Max count plus one.""" + + pass + + class MissingFields(ChecklistItem): + """Missing fields.""" + + pass + + class ExtraFields(ChecklistItem): + """Extra fields.""" + + pass + + class Truncated(ChecklistItem): + """Truncated serialization.""" + + pass + + class ExtraBytes(ChecklistItem): + """Extra bytes in serialization.""" + + pass + + class NewTypes(ChecklistItem): + """New type encoding tests.""" + + class IncorrectEncoding(ChecklistItem): + """Incorrect encoding.""" + + pass + + class OutOfBounds(ChecklistItem): + """Out-of-bounds checks.""" + + class Max(ChecklistItem): + """Max value for each field.""" + + pass + + class MaxPlusOne(ChecklistItem): + """Max value + 1 for each field.""" + + pass + + class ContractCreation(ChecklistItem): + """Contract creation with new tx type.""" + + pass + + class SenderAccount(ChecklistItem): + """Sender account modifications.""" + + class Nonce(ChecklistItem): + """Nonce increment.""" + + pass + + class Balance(ChecklistItem): + """Balance reduction.""" + + pass + + class BlockInteractions(ChecklistItem): + """Block level interactions.""" + + class SingleTx(ChecklistItem): + """Single transaction in block.""" + + class Invalid(ChecklistItem): + """Invalid gas limit.""" + + pass + + class Valid(ChecklistItem): + """Valid gas limit.""" + + pass + + class LastTx(ChecklistItem): + """Last transaction in block.""" + + class Valid(ChecklistItem): + """Valid cumulative gas.""" + + pass + + class Invalid(ChecklistItem): + """Invalid cumulative gas.""" + + pass + + class Eip7825(ChecklistItem): + """EIP-7825 gas limit tests.""" + + class Invalid(ChecklistItem): + """Exceeds EIP-7825 limit.""" + + pass + + class Valid(ChecklistItem): + """Within EIP-7825 limit.""" + + pass + + class MixedTxs(ChecklistItem): + """Mixed transaction types.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Before(ChecklistItem): + """Before fork activation.""" + + pass + + class BlockHeaderField(ChecklistItem): + """New block header field checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new block header field.""" + + class Genesis(ChecklistItem): + """Genesis value test.""" + + pass + + class ValueBehavior(ChecklistItem): + """Value behavior tests.""" + + class Accept(ChecklistItem): + """Block accepted with correct value.""" + + pass + + class Reject(ChecklistItem): + """Block rejected with incorrect value.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Initial(ChecklistItem): + """Initial value at fork.""" + + pass + + class Before(ChecklistItem): + """Before fork activation.""" + + pass + + class After(ChecklistItem): + """After fork activation.""" + + pass + + class BlockBodyField(ChecklistItem): + """New block body field checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new block body field.""" + + class ValueBehavior(ChecklistItem): + """Value behavior tests.""" + + class Accept(ChecklistItem): + """Block accepted with correct value.""" + + pass + + class Reject(ChecklistItem): + """Block rejected with incorrect value.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Before(ChecklistItem): + """Before fork activation.""" + + pass + + class After(ChecklistItem): + """After fork activation.""" + + pass + + class GasCostChanges(ChecklistItem): + """Gas cost changes checklist items.""" + + class Test(ChecklistItem): + """Test vectors for gas cost changes.""" + + class GasUpdatesMeasurement(ChecklistItem): + """Measure updated gas costs.""" + + pass + + class OutOfGas(ChecklistItem): + """Out-of-gas with new prices.""" + + pass + + class ForkTransition(ChecklistItem): + """Fork transition tests.""" + + class Before(ChecklistItem): + """Before fork activation.""" + + pass + + class After(ChecklistItem): + """After fork activation.""" + + pass + + class GasRefundsChanges(ChecklistItem): + """Gas refunds changes checklist items.""" + + class Test(ChecklistItem): + """Test vectors for gas refunds changes.""" + + class RefundCalculation(ChecklistItem): + """Refund calculation tests.""" + + class Over(ChecklistItem): + """Refund over limit.""" + + pass + + class Exact(ChecklistItem): + """Refund at limit.""" + + pass + + class Under(ChecklistItem): + """Refund under limit.""" + + pass + + class ExceptionalAbort(ChecklistItem): + """Exceptional abort tests.""" + + class Revertable(ChecklistItem): + """Revertable operations.""" + + class Revert(ChecklistItem): + """REVERT.""" + + pass + + class OutOfGas(ChecklistItem): + """Out-of-gas.""" + + pass + + class InvalidOpcode(ChecklistItem): + """Invalid opcode.""" + + pass + + class UpperRevert(ChecklistItem): + """Upper frame REVERT.""" + + pass + + class NonRevertable(ChecklistItem): + """Non-revertable operations.""" + + class Revert(ChecklistItem): + """REVERT at top frame.""" + + pass + + class OutOfGas(ChecklistItem): + """Out-of-gas at top frame.""" + + pass + + class InvalidOpcode(ChecklistItem): + """Invalid opcode at top frame.""" + + pass + + class CrossFunctional(ChecklistItem): + """Cross-functional tests.""" + + class CalldataCost(ChecklistItem): + """Calldata cost refunds.""" + + pass + + class BlobCountChanges(ChecklistItem): + """Blob count changes checklist items.""" + + class Test(ChecklistItem): + """Test vectors for blob count changes.""" + + class Eip4844BlobsChanges(ChecklistItem): + """EIP-4844 blobs test updates.""" + + pass + + class ExecutionLayerRequest(ChecklistItem): + """New execution layer request checklist items.""" + + class Test(ChecklistItem): + """Test vectors for new execution layer request.""" + + class CrossRequestType(ChecklistItem): + """Cross-request-type interaction.""" + + class Update(ChecklistItem): + """Update cross-request tests.""" + + pass diff --git a/src/ethereum_test_checklists/eip_checklist.pyi b/src/ethereum_test_checklists/eip_checklist.pyi new file mode 100644 index 00000000000..54c2b707da6 --- /dev/null +++ b/src/ethereum_test_checklists/eip_checklist.pyi @@ -0,0 +1,468 @@ +""" +Type stubs for EIP checklist - auto-generated. + +DO NOT EDIT MANUALLY - This file is generated by `uv run generate-checklist-stubs` +""" + +from typing import Any, Callable, TypeVar, overload + +import pytest + +F = TypeVar("F", bound=Callable[..., Any]) + +class _CallableChecklistItem: + """Base type for all callable checklist items.""" + + @overload + def __call__(self, func: F) -> F: ... + @overload + def __call__(self, *, eip: Any = ..., **kwargs: Any) -> pytest.MarkDecorator: ... + def __str__(self) -> str: ... + +class EIPChecklist: + class BlobCountChanges(_CallableChecklistItem): + class Test(_CallableChecklistItem): + Eip4844BlobsChanges: _CallableChecklistItem + + class BlockBodyField(_CallableChecklistItem): + class Test(_CallableChecklistItem): + class ForkTransition(_CallableChecklistItem): + After: _CallableChecklistItem + Before: _CallableChecklistItem + + class ValueBehavior(_CallableChecklistItem): + Accept: _CallableChecklistItem + Reject: _CallableChecklistItem + + class BlockHeaderField(_CallableChecklistItem): + class Test(_CallableChecklistItem): + Genesis: _CallableChecklistItem + + class ForkTransition(_CallableChecklistItem): + After: _CallableChecklistItem + Before: _CallableChecklistItem + Initial: _CallableChecklistItem + + class ValueBehavior(_CallableChecklistItem): + Accept: _CallableChecklistItem + Reject: _CallableChecklistItem + + class ExecutionLayerRequest(_CallableChecklistItem): + class Test(_CallableChecklistItem): + class CrossRequestType(_CallableChecklistItem): + Update: _CallableChecklistItem + + class GasCostChanges(_CallableChecklistItem): + class Test(_CallableChecklistItem): + GasUpdatesMeasurement: _CallableChecklistItem + OutOfGas: _CallableChecklistItem + + class ForkTransition(_CallableChecklistItem): + After: _CallableChecklistItem + Before: _CallableChecklistItem + + class GasRefundsChanges(_CallableChecklistItem): + class Test(_CallableChecklistItem): + class CrossFunctional(_CallableChecklistItem): + CalldataCost: _CallableChecklistItem + + class ExceptionalAbort(_CallableChecklistItem): + class NonRevertable(_CallableChecklistItem): + InvalidOpcode: _CallableChecklistItem + OutOfGas: _CallableChecklistItem + Revert: _CallableChecklistItem + + class Revertable(_CallableChecklistItem): + InvalidOpcode: _CallableChecklistItem + OutOfGas: _CallableChecklistItem + Revert: _CallableChecklistItem + UpperRevert: _CallableChecklistItem + + class RefundCalculation(_CallableChecklistItem): + Exact: _CallableChecklistItem + Over: _CallableChecklistItem + Under: _CallableChecklistItem + + class General(_CallableChecklistItem): + class CodeCoverage(_CallableChecklistItem): + Eels: _CallableChecklistItem + SecondClient: _CallableChecklistItem + TestCoverage: _CallableChecklistItem + + class Opcode(_CallableChecklistItem): + class Test(_CallableChecklistItem): + ExceptionalAbort: _CallableChecklistItem + StackOverflow: _CallableChecklistItem + StackUnderflow: _CallableChecklistItem + + class ContractCreation(_CallableChecklistItem): + Address: _CallableChecklistItem + Recursive: _CallableChecklistItem + + class Failure(_CallableChecklistItem): + Collision: _CallableChecklistItem + InsufficientValue: _CallableChecklistItem + Oog: _CallableChecklistItem + + class DataPortion(_CallableChecklistItem): + AllZeros: _CallableChecklistItem + Jump: _CallableChecklistItem + MaxValue: _CallableChecklistItem + + class ExecutionContext(_CallableChecklistItem): + BlockContext: _CallableChecklistItem + Call: _CallableChecklistItem + Callcode: _CallableChecklistItem + SetCode: _CallableChecklistItem + TxContext: _CallableChecklistItem + + class Delegatecall(_CallableChecklistItem): + Balance: _CallableChecklistItem + Code: _CallableChecklistItem + Storage: _CallableChecklistItem + + class Initcode(_CallableChecklistItem): + Reentry: _CallableChecklistItem + + class Behavior(_CallableChecklistItem): + Opcode: _CallableChecklistItem + Tx: _CallableChecklistItem + + class Staticcall(_CallableChecklistItem): + BanCheck: _CallableChecklistItem + BanNoModification: _CallableChecklistItem + SubCalls: _CallableChecklistItem + + class ForkTransition(_CallableChecklistItem): + At: _CallableChecklistItem + Invalid: _CallableChecklistItem + + class GasUsage(_CallableChecklistItem): + MemoryExpansion: _CallableChecklistItem + Normal: _CallableChecklistItem + OutOfGasExecution: _CallableChecklistItem + OutOfGasMemory: _CallableChecklistItem + + class OrderOfOperations(_CallableChecklistItem): + Exact: _CallableChecklistItem + Oog: _CallableChecklistItem + + class MemExp(_CallableChecklistItem): + SingleByte: _CallableChecklistItem + SixtyFourBytes: _CallableChecklistItem + ThirtyOneBytes: _CallableChecklistItem + ThirtyThreeBytes: _CallableChecklistItem + ThirtyTwoBytes: _CallableChecklistItem + TwoSixtyFourBytes: _CallableChecklistItem + TwoSixtyFourMinusOneBytes: _CallableChecklistItem + TwoThirtyTwoBytes: _CallableChecklistItem + TwoThirtyTwoMinusOneBytes: _CallableChecklistItem + TwoTwoFiftySixMinusOneBytes: _CallableChecklistItem + ZeroBytesMaxOffset: _CallableChecklistItem + ZeroBytesZeroOffset: _CallableChecklistItem + + class OutOfBounds(_CallableChecklistItem): + class Verify(_CallableChecklistItem): + Max: _CallableChecklistItem + MaxPlusOne: _CallableChecklistItem + + class ReturnData(_CallableChecklistItem): + class Buffer(_CallableChecklistItem): + Current: _CallableChecklistItem + Parent: _CallableChecklistItem + + class StackComplexOperations(_CallableChecklistItem): + class DataPortionVariables(_CallableChecklistItem): + Bottom: _CallableChecklistItem + Middle: _CallableChecklistItem + Top: _CallableChecklistItem + + class StackHeights(_CallableChecklistItem): + Even: _CallableChecklistItem + Odd: _CallableChecklistItem + Zero: _CallableChecklistItem + + class Terminating(_CallableChecklistItem): + class Rollback(_CallableChecklistItem): + Balance: _CallableChecklistItem + Contracts: _CallableChecklistItem + Logs: _CallableChecklistItem + Nonce: _CallableChecklistItem + Storage: _CallableChecklistItem + + class Scenarios(_CallableChecklistItem): + Initcode: _CallableChecklistItem + SubLevel: _CallableChecklistItem + TopLevel: _CallableChecklistItem + + class Precompile(_CallableChecklistItem): + class Test(_CallableChecklistItem): + ExcessiveGasUsage: _CallableChecklistItem + + class CallContexts(_CallableChecklistItem): + Callcode: _CallableChecklistItem + Delegate: _CallableChecklistItem + Normal: _CallableChecklistItem + SetCode: _CallableChecklistItem + Static: _CallableChecklistItem + TxEntry: _CallableChecklistItem + + class Initcode(_CallableChecklistItem): + CREATE: _CallableChecklistItem + Tx: _CallableChecklistItem + + class ForkTransition(_CallableChecklistItem): + class After(_CallableChecklistItem): + Warm: _CallableChecklistItem + + class Before(_CallableChecklistItem): + Cold: _CallableChecklistItem + InvalidInput: _CallableChecklistItem + ZeroGas: _CallableChecklistItem + + class GasUsage(_CallableChecklistItem): + class Constant(_CallableChecklistItem): + Exact: _CallableChecklistItem + Oog: _CallableChecklistItem + + class Dynamic(_CallableChecklistItem): + Exact: _CallableChecklistItem + Oog: _CallableChecklistItem + + class InputLengths(_CallableChecklistItem): + Zero: _CallableChecklistItem + + class Dynamic(_CallableChecklistItem): + TooLong: _CallableChecklistItem + TooShort: _CallableChecklistItem + Valid: _CallableChecklistItem + + class Static(_CallableChecklistItem): + Correct: _CallableChecklistItem + TooLong: _CallableChecklistItem + TooShort: _CallableChecklistItem + + class Inputs(_CallableChecklistItem): + AllZeros: _CallableChecklistItem + MaxValues: _CallableChecklistItem + + class Invalid(_CallableChecklistItem): + Corrupted: _CallableChecklistItem + Crypto: _CallableChecklistItem + + class Valid(_CallableChecklistItem): + Boundary: _CallableChecklistItem + Crypto: _CallableChecklistItem + + class OutOfBounds(_CallableChecklistItem): + Max: _CallableChecklistItem + MaxPlusOne: _CallableChecklistItem + + class ValueTransfer(_CallableChecklistItem): + NoFee: _CallableChecklistItem + + class Fee(_CallableChecklistItem): + Exact: _CallableChecklistItem + Over: _CallableChecklistItem + Under: _CallableChecklistItem + + class RemovedPrecompile(_CallableChecklistItem): + class Test(_CallableChecklistItem): + class ForkTransition(_CallableChecklistItem): + Operational: _CallableChecklistItem + + class After(_CallableChecklistItem): + Cold: _CallableChecklistItem + + class Before(_CallableChecklistItem): + Warm: _CallableChecklistItem + + class SystemContract(_CallableChecklistItem): + class Test(_CallableChecklistItem): + class CallContexts(_CallableChecklistItem): + Callcode: _CallableChecklistItem + Delegate: _CallableChecklistItem + Normal: _CallableChecklistItem + SetCode: _CallableChecklistItem + Static: _CallableChecklistItem + TxEntry: _CallableChecklistItem + + class Initcode(_CallableChecklistItem): + CREATE: _CallableChecklistItem + Tx: _CallableChecklistItem + + class ContractSubstitution(_CallableChecklistItem): + GasLimitFailure: _CallableChecklistItem + GasLimitSuccess: _CallableChecklistItem + Logs: _CallableChecklistItem + RaisesException: _CallableChecklistItem + ReturnLengths: _CallableChecklistItem + + class ContractVariations(_CallableChecklistItem): + Networks: _CallableChecklistItem + + class Deployment(_CallableChecklistItem): + Address: _CallableChecklistItem + Missing: _CallableChecklistItem + + class ExcessiveGas(_CallableChecklistItem): + BlockGas: _CallableChecklistItem + SystemCall: _CallableChecklistItem + + class ForkTransition(_CallableChecklistItem): + CallBeforeFork: _CallableChecklistItem + + class GasUsage(_CallableChecklistItem): + class Constant(_CallableChecklistItem): + Exact: _CallableChecklistItem + Oog: _CallableChecklistItem + + class Dynamic(_CallableChecklistItem): + Exact: _CallableChecklistItem + Oog: _CallableChecklistItem + + class InputLengths(_CallableChecklistItem): + Zero: _CallableChecklistItem + + class Dynamic(_CallableChecklistItem): + TooLong: _CallableChecklistItem + TooShort: _CallableChecklistItem + Valid: _CallableChecklistItem + + class Static(_CallableChecklistItem): + Correct: _CallableChecklistItem + TooLong: _CallableChecklistItem + TooShort: _CallableChecklistItem + + class Inputs(_CallableChecklistItem): + AllZeros: _CallableChecklistItem + Boundary: _CallableChecklistItem + MaxValues: _CallableChecklistItem + Valid: _CallableChecklistItem + + class Invalid(_CallableChecklistItem): + Checks: _CallableChecklistItem + Corrupted: _CallableChecklistItem + Crypto: _CallableChecklistItem + + class OutOfBounds(_CallableChecklistItem): + Max: _CallableChecklistItem + MaxPlusOne: _CallableChecklistItem + + class ValueTransfer(_CallableChecklistItem): + NoFee: _CallableChecklistItem + + class Fee(_CallableChecklistItem): + Exact: _CallableChecklistItem + Over: _CallableChecklistItem + Under: _CallableChecklistItem + + class TransactionType(_CallableChecklistItem): + class Test(_CallableChecklistItem): + ContractCreation: _CallableChecklistItem + + class BlockInteractions(_CallableChecklistItem): + MixedTxs: _CallableChecklistItem + + class Eip7825(_CallableChecklistItem): + Invalid: _CallableChecklistItem + Valid: _CallableChecklistItem + + class LastTx(_CallableChecklistItem): + Invalid: _CallableChecklistItem + Valid: _CallableChecklistItem + + class SingleTx(_CallableChecklistItem): + Invalid: _CallableChecklistItem + Valid: _CallableChecklistItem + + class Encoding(_CallableChecklistItem): + ExtraBytes: _CallableChecklistItem + ExtraFields: _CallableChecklistItem + MissingFields: _CallableChecklistItem + Truncated: _CallableChecklistItem + + class FieldSizes(_CallableChecklistItem): + LeadingZero: _CallableChecklistItem + RemoveByte: _CallableChecklistItem + + class ListField(_CallableChecklistItem): + Max: _CallableChecklistItem + MaxPlusOne: _CallableChecklistItem + Zero: _CallableChecklistItem + + class NewTypes(_CallableChecklistItem): + IncorrectEncoding: _CallableChecklistItem + + class ForkTransition(_CallableChecklistItem): + Before: _CallableChecklistItem + + class IntrinsicValidity(_CallableChecklistItem): + ChainId: _CallableChecklistItem + DataFloorAboveIntrinsicGasCost: _CallableChecklistItem + NonceExact: _CallableChecklistItem + NonceMinusOne: _CallableChecklistItem + NoncePlusOne: _CallableChecklistItem + To: _CallableChecklistItem + ValueNonZeroInsufficientBalance: _CallableChecklistItem + ValueNonZeroSufficientBalance: _CallableChecklistItem + ValueZeroInsufficientBalance: _CallableChecklistItem + ValueZeroSufficientBalance: _CallableChecklistItem + + class GasLimit(_CallableChecklistItem): + Exact: _CallableChecklistItem + Insufficient: _CallableChecklistItem + + class MaxFee(_CallableChecklistItem): + BaseEqual: _CallableChecklistItem + BaseLower: _CallableChecklistItem + MaxPriorityEqualToMaxFee: _CallableChecklistItem + MaxPriorityLowerThanMaxFee: _CallableChecklistItem + + class OutOfBounds(_CallableChecklistItem): + Max: _CallableChecklistItem + MaxPlusOne: _CallableChecklistItem + + class SenderAccount(_CallableChecklistItem): + Balance: _CallableChecklistItem + Nonce: _CallableChecklistItem + + class Signature(_CallableChecklistItem): + class Invalid(_CallableChecklistItem): + FieldOutsideCurve: _CallableChecklistItem + + class R(_CallableChecklistItem): + Max: _CallableChecklistItem + MaxMinusOne: _CallableChecklistItem + Secp256k1n: _CallableChecklistItem + Secp256k1nMinusOne: _CallableChecklistItem + Secp256k1nPlusOne: _CallableChecklistItem + Zero: _CallableChecklistItem + + class S(_CallableChecklistItem): + Complement: _CallableChecklistItem + Max: _CallableChecklistItem + MaxMinusOne: _CallableChecklistItem + Secp256k1n: _CallableChecklistItem + Secp256k1nHalf: _CallableChecklistItem + Secp256k1nHalfMinusOne: _CallableChecklistItem + Secp256k1nHalfPlusOne: _CallableChecklistItem + Secp256k1nMinusOne: _CallableChecklistItem + Secp256k1nPlusOne: _CallableChecklistItem + Zero: _CallableChecklistItem + + class V(_CallableChecklistItem): + Max: _CallableChecklistItem + ThirtyFive: _CallableChecklistItem + ThirtySix: _CallableChecklistItem + TwentyEight: _CallableChecklistItem + TwentySeven: _CallableChecklistItem + Two: _CallableChecklistItem + + class TxScopedAttributes(_CallableChecklistItem): + OlderTxTypes: _CallableChecklistItem + Read: _CallableChecklistItem + + class Persistent(_CallableChecklistItem): + Reset: _CallableChecklistItem + Throughout: _CallableChecklistItem diff --git a/src/ethereum_test_checklists/tests/__init__.py b/src/ethereum_test_checklists/tests/__init__.py new file mode 100644 index 00000000000..bdc7d71b87e --- /dev/null +++ b/src/ethereum_test_checklists/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for ethereum_test_checklists.""" diff --git a/src/ethereum_test_checklists/tests/test_checklist_template_consistency.py b/src/ethereum_test_checklists/tests/test_checklist_template_consistency.py new file mode 100644 index 00000000000..1e99199cde8 --- /dev/null +++ b/src/ethereum_test_checklists/tests/test_checklist_template_consistency.py @@ -0,0 +1,197 @@ +"""Test consistency between checklist template and EIPChecklist class.""" + +import re +from pathlib import Path +from typing import Set + +import pytest + +from ethereum_test_checklists.eip_checklist import EIPChecklist + +TEMPLATE_PATH = ( + Path(__file__).parent.parent.parent.parent + / "docs" + / "writing_tests" + / "checklist_templates" + / "eip_testing_checklist_template.md" +) + + +def extract_markdown_ids(markdown_content: str) -> Set[str]: + """Extract all checklist IDs from markdown content.""" + # Pattern to match IDs in markdown tables (between backticks in ID column) + pattern = r"\|\s*`([^`]+)`\s*\|" + + ids = set() + for match in re.finditer(pattern, markdown_content): + potential_id = match.group(1) + # Filter out non-ID content - IDs should contain forward slashes + if "/" in potential_id: + ids.add(potential_id) + + return ids + + +def get_all_checklist_ids(obj, current_path="") -> Set[str]: + """Recursively extract all checklist IDs from EIPChecklist and its children.""" + ids = set() + + # Iterate through all attributes of the object + for attr_name in dir(obj): + # Skip private attributes and methods + if attr_name.startswith("_"): + continue + + attr = getattr(obj, attr_name) + + # Check if this is a class with a _path attribute (our checklist items) + if isinstance(attr, type) and hasattr(attr, "_path"): + # Get the full path for this item + item_path = str(attr) + if item_path: # Only add non-empty paths + ids.add(item_path) + + # Recursively get IDs from nested classes + nested_ids = get_all_checklist_ids(attr) + ids.update(nested_ids) + + return ids + + +def test_checklist_template_consistency(): + """Test that all IDs in markdown template match EIPChecklist class exactly.""" + # Read the markdown template + with open(TEMPLATE_PATH, "r", encoding="utf-8") as f: + markdown_content = f.read() + + # Extract IDs from both sources + markdown_ids = extract_markdown_ids(markdown_content) + checklist_ids = get_all_checklist_ids(EIPChecklist) + + # Find differences + missing_in_checklist = markdown_ids - checklist_ids + missing_in_markdown = checklist_ids - markdown_ids + + # Create detailed error messages + errors = [] + + if missing_in_checklist: + errors.append( + f"IDs found in markdown template but missing in EIPChecklist class " + f"({len(missing_in_checklist)} items):\n" + + "\n".join(f" - `{id_}`" for id_ in sorted(missing_in_checklist)) + ) + + if missing_in_markdown: + for id_ in missing_in_markdown: + if any(item.startswith(id_ + "/") for item in checklist_ids): + continue + + errors.append(f"ID `{id_}` not found in markdown template") + + if errors: + error_message = f"\nTotal markdown IDs: {len(markdown_ids)}\n" + error_message += f"Total checklist IDs: {len(checklist_ids)}\n\n" + error_message += "\n\n".join(errors) + pytest.fail(error_message) + + +def test_checklist_template_exists(): + """Test that the checklist template file exists.""" + assert TEMPLATE_PATH.exists(), f"Checklist template not found at {TEMPLATE_PATH}" + + +def test_eip_checklist_class_structure(): + """Test that the EIPChecklist class has expected structure.""" + assert hasattr(EIPChecklist, "General"), "EIPChecklist should have General class" + assert hasattr(EIPChecklist, "Opcode"), "EIPChecklist should have Opcode class" + assert hasattr(EIPChecklist, "Precompile"), "EIPChecklist should have Precompile class" + + # Test that the metaclass is working correctly + assert str(EIPChecklist.General.CodeCoverage.Eels) == "general/code_coverage/eels" + assert ( + str(EIPChecklist.Opcode.Test.MemExp.ZeroBytesZeroOffset) + == "opcode/test/mem_exp/zero_bytes_zero_offset" + ) + + +def test_id_extraction_functions(): + """Test that our ID extraction functions work correctly.""" + # Test markdown extraction + sample_markdown = """ + | ID | Description | Status | Tests | + | `test/example/id` | Test description | | | + | `another/test/path` | Another test | | | + """ + + ids = extract_markdown_ids(sample_markdown) + assert "test/example/id" in ids + assert "another/test/path" in ids + + # Test checklist extraction + checklist_ids = get_all_checklist_ids(EIPChecklist) + assert len(checklist_ids) > 0 + assert "general/code_coverage/eels" in checklist_ids + + +def test_eip_checklist_decorator_usage(): + """Test EIPChecklist items work correctly as decorators both with and without parentheses.""" + + # Test decorator with parentheses + @EIPChecklist.Opcode.Test.StackComplexOperations() + def test_function_with_parens(): + pass + + # Verify the marker was applied + markers = list(test_function_with_parens.pytestmark) + assert len(markers) >= 1 + eip_markers = [m for m in markers if m.name == "eip_checklist"] + assert len(eip_markers) == 1 + assert eip_markers[0].args == ("opcode/test/stack_complex_operations",) + + # Test decorator without parentheses (direct usage - this is the key fix for issue #1) + @EIPChecklist.Opcode.Test.StackOverflow + def test_function_no_parens(): + pass + + # Verify the marker was applied + markers = list(test_function_no_parens.pytestmark) + eip_markers = [m for m in markers if m.name == "eip_checklist"] + assert len(eip_markers) == 1 + assert eip_markers[0].args == ("opcode/test/stack_overflow",) + + +def test_eip_checklist_pytest_param_usage(): + """Test that EIPChecklist works correctly in pytest.param marks.""" + # Test that parentheses form works in pytest.param + param_with_parens = pytest.param( + "test_value", marks=EIPChecklist.Opcode.Test.GasUsage.Normal(), id="gas_test" + ) + + # Verify the parameter was created successfully + assert param_with_parens.values == ("test_value",) + assert param_with_parens.id == "gas_test" + assert len(param_with_parens.marks) == 1 + assert param_with_parens.marks[0].name == "eip_checklist" + assert param_with_parens.marks[0].args == ("opcode/test/gas_usage/normal",) + + # Test that multiple marks work + param_multiple_marks = pytest.param( + "test_value", + marks=[EIPChecklist.Opcode.Test.StackComplexOperations(), pytest.mark.slow], + id="complex_test", + ) + + # Verify multiple marks + assert len(param_multiple_marks.marks) == 2 + eip_mark = next(m for m in param_multiple_marks.marks if m.name == "eip_checklist") + assert eip_mark.args == ("opcode/test/stack_complex_operations",) + + # Test that non-parentheses form fails gracefully with pytest.param + # (This documents the expected behavior - parentheses are required) + with pytest.raises((TypeError, AssertionError)): + pytest.param( + "test_value", + marks=EIPChecklist.Opcode.Test.StackOverflow, # Without () should fail + id="should_fail", + ) diff --git a/src/pytest_plugins/consume/hive_engine_test/__init__.py b/src/pytest_plugins/consume/hive_engine_test/__init__.py new file mode 100644 index 00000000000..2d1322a5332 --- /dev/null +++ b/src/pytest_plugins/consume/hive_engine_test/__init__.py @@ -0,0 +1 @@ +"""Hive engine test consumer plugin.""" diff --git a/src/pytest_plugins/consume/hive_simulators_reorg/__init__.py b/src/pytest_plugins/consume/hive_simulators_reorg/__init__.py new file mode 100644 index 00000000000..59ca949d150 --- /dev/null +++ b/src/pytest_plugins/consume/hive_simulators_reorg/__init__.py @@ -0,0 +1 @@ +"""Hive simulators reorganization consumer plugin.""" diff --git a/src/pytest_plugins/filler/eip_checklist.py b/src/pytest_plugins/filler/eip_checklist.py index 6f4971942b8..5cd435bdbfb 100644 --- a/src/pytest_plugins/filler/eip_checklist.py +++ b/src/pytest_plugins/filler/eip_checklist.py @@ -129,12 +129,30 @@ def __str__(self) -> str: if item := EIPItem.from_checklist_line(line=line, line_number=i + 1): TEMPLATE_ITEMS[item.id] = item + +def template_items() -> Dict[str, EIPItem]: + """Return a copy of the template items.""" + new_items = {} + for test_id, item in TEMPLATE_ITEMS.items(): + new_items[test_id] = EIPItem( + id=item.id, + line_number=item.line_number, + description=item.description, + tests=set(), + ) + return new_items + + ALL_IDS = set(TEMPLATE_ITEMS.keys()) def resolve_id(item_id: str) -> Set[str]: """Resolve an item ID to a set of checklist IDs.""" - covered_ids = {checklist_id for checklist_id in ALL_IDS if checklist_id.startswith(item_id)} + covered_ids = { + checklist_id + for checklist_id in ALL_IDS + if checklist_id == item_id or checklist_id.startswith(item_id + "/") + } return covered_ids @@ -143,7 +161,7 @@ class EIP: """Represents an EIP and its checklist.""" number: int - items: Dict[str, EIPItem] = field(default_factory=TEMPLATE_ITEMS.copy) + items: Dict[str, EIPItem] = field(default_factory=template_items) path: Path | None = None def add_covered_test(self, checklist_id: str, node_id: str) -> None: @@ -328,6 +346,7 @@ def collect_from_item(self, item: pytest.Item, primary_eip: EIP | None) -> None: eips += [self.get_eip(eip) for eip in additional_eips] for item_id in marker.args: + item_id = str(item_id) covered_ids = resolve_id(item_id.strip()) if not covered_ids: logger.warning( diff --git a/src/pytest_plugins/filler/tests/test_eip_checklist.py b/src/pytest_plugins/filler/tests/test_eip_checklist.py index 29511751128..1734dbfca30 100644 --- a/src/pytest_plugins/filler/tests/test_eip_checklist.py +++ b/src/pytest_plugins/filler/tests/test_eip_checklist.py @@ -1,5 +1,6 @@ """Test the EIP checklist plugin functionality.""" +import re import textwrap @@ -17,21 +18,18 @@ def test_eip_checklist_collection(testdir): import pytest from ethereum_test_tools import StateTestFiller + from ethereum_test_checklists import EIPChecklist + REFERENCE_SPEC_GIT_PATH = "N/A" REFERENCE_SPEC_VERSION = "N/A" @pytest.mark.valid_at("Prague") - @pytest.mark.eip_checklist( - "new_transaction_type/test/intrinsic_validity/gas_limit/exact" - ) + @EIPChecklist.TransactionType.Test.IntrinsicValidity.GasLimit.Exact() def test_exact_gas(state_test: StateTestFiller): pass @pytest.mark.valid_at("Prague") - @pytest.mark.eip_checklist( - "new_transaction_type/test/signature/invalid/v/2", - eip=[7702, 2930] - ) + @EIPChecklist.TransactionType.Test.Signature.Invalid.V.Two(eip=[2930]) def test_invalid_v(state_test: StateTestFiller): pass """ @@ -49,7 +47,7 @@ def test_invalid_v(state_test: StateTestFiller): ) berlin_tests_dir = tests_dir.mkdir("berlin") - eip_2930_tests_dir = berlin_tests_dir.mkdir("eip2930_set_code_tx") + eip_2930_tests_dir = berlin_tests_dir.mkdir("eip2930_access_list") test_2930_module = eip_2930_tests_dir.join("test_eip2930.py") test_2930_module.write( textwrap.dedent( @@ -70,7 +68,7 @@ def test_berlin_one(state_test: StateTestFiller): test_2930_n_a_file.write( textwrap.dedent( """ - new_system_contract = DEBUG NOT APPLICABLE REASON + system_contract = DEBUG NOT APPLICABLE REASON """ ) ) @@ -94,20 +92,19 @@ def test_berlin_one(state_test: StateTestFiller): # Check that checklists were generated checklist_dir = testdir.tmpdir / "checklists" assert checklist_dir.exists() + checklist_file = checklist_dir / "eip7702_checklist.md" assert checklist_file.exists() # Verify the checklist contains the expected markers - content = checklist_file.read() - assert "โœ…" in content - assert "test_exact_gas" in content - assert "test_invalid_v" in content - assert "DEBUG EXTERNAL COVERAGE REASON" in content + content = checklist_file.readlines() + assert any(re.search(r"โœ….*test_exact_gas", line) for line in content) + assert any(re.search(r"โœ….*test_invalid_v", line) for line in content) + assert any(re.search(r"โœ….*DEBUG EXTERNAL COVERAGE REASON", line) for line in content) checklist_file = checklist_dir / "eip2930_checklist.md" assert checklist_file.exists() - content = checklist_file.read() - assert "โœ…" in content - assert "test_invalid_v" in content - assert "N/A" in content - assert "DEBUG NOT APPLICABLE REASON" in content + content = checklist_file.readlines() + assert not any(re.search(r"โœ….*test_exact_gas", line) for line in content) + assert any(re.search(r"โœ….*test_invalid_v", line) for line in content) + assert any(re.search(r"N/A.*DEBUG NOT APPLICABLE REASON", line) for line in content) diff --git a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py index 625ad7a98aa..56e3e7ab764 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py +++ b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py @@ -31,8 +31,8 @@ # Source: https://github.com/C2SP/wycheproof/blob/main/testvectors/ecdsa_secp256r1_sha256_test.json ) @pytest.mark.parametrize("precompile_address", [Spec.P256VERIFY], ids=[""]) -@pytest.mark.eip_checklist("new_precompile/test/call_contexts/normal") -@pytest.mark.eip_checklist("new_precompile/test/inputs/valid") +@pytest.mark.eip_checklist("precompile/test/call_contexts/normal") +@pytest.mark.eip_checklist("precompile/test/inputs/valid") def test_valid(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transaction): """Test P256Verify precompile.""" state_test(env=Environment(), pre=pre, post=post, tx=tx) @@ -94,13 +94,13 @@ def test_valid(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transact ) @pytest.mark.parametrize("expected_output", [Spec.INVALID_RETURN_VALUE], ids=[""]) @pytest.mark.parametrize("precompile_address", [Spec.P256VERIFY], ids=[""]) -@pytest.mark.eip_checklist("new_precompile/test/inputs/all_zeros") -@pytest.mark.eip_checklist("new_precompile/test/inputs/invalid") -@pytest.mark.eip_checklist("new_precompile/test/inputs/invalid/crypto") -@pytest.mark.eip_checklist("new_precompile/test/inputs/invalid/corrupted") -@pytest.mark.eip_checklist("new_precompile/test/input_lengths/static/correct") -@pytest.mark.eip_checklist("new_precompile/test/input_lengths/static/too_short") -@pytest.mark.eip_checklist("new_precompile/test/input_lengths/static/too_long") +@pytest.mark.eip_checklist("precompile/test/inputs/all_zeros") +@pytest.mark.eip_checklist("precompile/test/inputs/invalid") +@pytest.mark.eip_checklist("precompile/test/inputs/invalid/crypto") +@pytest.mark.eip_checklist("precompile/test/inputs/invalid/corrupted") +@pytest.mark.eip_checklist("precompile/test/input_lengths/static/correct") +@pytest.mark.eip_checklist("precompile/test/input_lengths/static/too_short") +@pytest.mark.eip_checklist("precompile/test/input_lengths/static/too_long") def test_invalid(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transaction): """Negative tests for the P256VERIFY precompile.""" state_test(env=Environment(), pre=pre, post=post, tx=tx) @@ -126,8 +126,8 @@ def test_invalid(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transa ], ) @pytest.mark.parametrize("precompile_address", [Spec.P256VERIFY], ids=[""]) -@pytest.mark.eip_checklist("new_precompile/test/gas_usage/constant/exact") -@pytest.mark.eip_checklist("new_precompile/test/gas_usage/constant/oog") +@pytest.mark.eip_checklist("precompile/test/gas_usage/constant/exact") +@pytest.mark.eip_checklist("precompile/test/gas_usage/constant/oog") def test_gas(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transaction): """Test P256Verify precompile gas requirements.""" state_test(env=Environment(), pre=pre, post=post, tx=tx) @@ -152,9 +152,9 @@ def test_gas(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transactio ], ) @pytest.mark.parametrize("precompile_address", [Spec.P256VERIFY], ids=[""]) -@pytest.mark.eip_checklist("new_precompile/test/call_contexts/delegate") -@pytest.mark.eip_checklist("new_precompile/test/call_contexts/static") -@pytest.mark.eip_checklist("new_precompile/test/call_contexts/callcode") +@pytest.mark.eip_checklist("precompile/test/call_contexts/delegate") +@pytest.mark.eip_checklist("precompile/test/call_contexts/static") +@pytest.mark.eip_checklist("precompile/test/call_contexts/callcode") def test_call_types( state_test: StateTestFiller, pre: Alloc, @@ -176,7 +176,7 @@ def test_call_types( ), ], ) -@pytest.mark.eip_checklist("new_precompile/test/call_contexts/tx_entry") +@pytest.mark.eip_checklist("precompile/test/call_contexts/tx_entry") def test_precompile_as_tx_entry_point( state_test: StateTestFiller, pre: Alloc, diff --git a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify_before_fork.py b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify_before_fork.py index 31175d1204d..53bbef89fc3 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify_before_fork.py +++ b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify_before_fork.py @@ -27,7 +27,7 @@ ], ) @pytest.mark.parametrize("expected_output,call_succeeds", [pytest.param(b"", True, id="")]) -@pytest.mark.eip_checklist("new_precompile/test/fork_transition/before/invalid_input") +@pytest.mark.eip_checklist("precompile/test/fork_transition/before/invalid_input") def test_precompile_before_fork( state_test: StateTestFiller, pre: Alloc, diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py index a0b05ba0622..afb583c35c9 100644 --- a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py +++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py @@ -2522,7 +2522,7 @@ def test_set_code_to_log( @pytest.mark.with_all_call_opcodes @pytest.mark.with_all_precompiles -@pytest.mark.eip_checklist("new_precompile/test/call_contexts/set_code", eips=[7951]) +@pytest.mark.eip_checklist("precompile/test/call_contexts/set_code", eips=[7951]) def test_set_code_to_precompile( state_test: StateTestFiller, pre: Alloc,